5

I have a base class like that:

public class BaseClass : IEditableObject {

    public BaseClass() {

    }

    public Guid Id { get; set; }

    public void BeginEdit() {

    }
    public void CancelEdit() {

    }
    public void EndEdit() {

    }
}

And I have 2 derived classes like that:

public class User : BaseClass {

    [Column( "UserFirstName" )]
    public string FirstName {
        get;
        set;
    }

    [Column( "UserLastName" )]
    public string LastName {
        get;
        set;
    }
}

public class School : BaseClass {
    [Column( "SchoolName" )]
    public string Name {
        get;
        set;
    }
}

I am using Entity Framework Code-First and configuring these classes in my context class:

public class MyContext : DbContext {

    public MyContext() : base() {
        Database.SetInitializer( new MigrateDatabaseToLatestVersion<MyContext, Configuration>() );
    }

    public DbSet<User> Users { get; set; }

    public DbSet<School> Schools { get; set; }

    protected override void OnModelCreating( DbModelBuilder modelBuilder ) {
        base.OnModelCreating( modelBuilder );
    }

}

When I run the program database and tables are created but primary key column names are Id for each table. I want the column name to be UserId or SchoolId.

Therefore I must configure entities on model creating to change column names with TableNameId

I could do this job as well:

modelBuilder.Entity<User>().Property( i => i.Id ).HasColumnName( "UserId" );
modelBuilder.Entity<School>().Property( i => i.Id ).HasColumnName( "SchoolId" );

Assume that I have hundreds of classes, I'll make configurations one by one for each entity so this is a huge waste of time.

How can I do this job dynamically using iterate or something else I don't know?

Cœur
  • 37,241
  • 25
  • 195
  • 267
test user
  • 55
  • 1
  • 6

2 Answers2

5

You can use Custom Code First Conventions for this. In your case:

modelBuilder.Properties().Where(p => p.Name == "Id")
            .Configure(c => c.HasColumnName(c.ClrPropertyInfo.ReflectedType.Name + "Id"));
Gert Arnold
  • 105,341
  • 31
  • 202
  • 291
  • I tried your solution but column names are BaseId now. – test user May 03 '17 at 14:17
  • Ah yes, please see the modification. – Gert Arnold May 03 '17 at 14:21
  • You've posted this when I was preparing mine, so I was wondering if I should post it since it's basically another variation of your answer. At the end decided to post it for the record :) +1 – Ivan Stoev May 03 '17 at 14:26
  • 2
    That's OK! I think your solution is cleaner when OP wants to have the convention for the BaseClass subtypes only, mine would be for any Id property. Now OP has options, great! – Gert Arnold May 03 '17 at 14:27
5

You can use DbModelBuilder.Types<T> method to apply your custom convention on all BaseClass derived entities:

modelBuilder.Types<BaseClass>().Configure(c => 
    c.Property(e => e.Id).HasColumnName(c.ClrType.Name + "Id")
);
Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343