如何在实体框架上下文类中动态更改模型创建的列名

tes*_*ser 5 c# entity-framework dbcontext ef-fluent-api

我有一个这样的基类:

public class BaseClass : IEditableObject {

    public BaseClass() {

    }

    public Guid Id { get; set; }

    public void BeginEdit() {

    }
    public void CancelEdit() {

    }
    public void EndEdit() {

    }
}
Run Code Online (Sandbox Code Playgroud)

我有 2 个这样的派生类:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在使用 Entity Framework Code-First 并在我的上下文类中配置这些类:

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 );
    }

}
Run Code Online (Sandbox Code Playgroud)

当我运行程序数据库并创建表时,但每个表的主键列名称都是Id。我希望列名是UserIdSchoolId

因此,我必须在模型创建时配置实体以使用TableNameId更改列名

我也可以做这个工作:

modelBuilder.Entity<User>().Property( i => i.Id ).HasColumnName( "UserId" );
modelBuilder.Entity<School>().Property( i => i.Id ).HasColumnName( "SchoolId" );
Run Code Online (Sandbox Code Playgroud)

假设我有数百个类,我会为每个实体一一进行配置,因此这是非常浪费时间的。

我怎样才能使用迭代或其他我不知道的东西动态地完成这项工作?

Ger*_*old 5

您可以为此使用自定义代码优先约定。在你的情况下:

modelBuilder.Properties().Where(p => p.Name == "Id")
            .Configure(c => c.HasColumnName(c.ClrPropertyInfo.ReflectedType.Name + "Id"));
Run Code Online (Sandbox Code Playgroud)

  • 没关系!我认为当 OP 只想为 BaseClass 子类型制定约定时,您的解决方案更清晰,我的将适用于任何 Id 属性。现在 OP 有了选择,太棒了! (2认同)

Iva*_*oev 5

您可以使用DbModelBuilder.Types<T>method 将您的自定义约定应用于所有BaseClass派生实体:

modelBuilder.Types<BaseClass>().Configure(c => 
    c.Property(e => e.Id).HasColumnName(c.ClrType.Name + "Id")
);
Run Code Online (Sandbox Code Playgroud)