使用Entity Framework 6中的自定义约定控制列映射

Bra*_*ner 9 c# entity-framework entity-framework-6

我有一个类TypeEntity将作为几十个实体的基类.我正在使用TPC,所以我需要将基类的所有属性映射到具有具体类名称的表,并将该Key字段设置为数据库生成.

目前我正在EntityTypeConfiguration为每个实体类型执行此操作,如下所示:

class LineItemType : EntityTypeConfiguration<Models.LineItemType>
{
    public LineItemType()
    {
        this.Property(e => e.Key)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

        this.Map(e => e.MapInheritedProperties()
                       .ToTable(nameof(LineItemType)));
    }
}
Run Code Online (Sandbox Code Playgroud)

这工作正常,但非常重复.我必须记住为每个继承的类型创建一个配置类TypeEntity,设置键,并映射继承的属性.这似乎是一个习惯的理想情况Convention.


我创建了TypeEntityTpcConvention Convention如下:

class TypeEntityTpcConvention : Convention
{
    public TypeEntityTpcConvention()
    {
        this.Types<TypeEntity>()
            .Configure(e => e.Property(p => p.Key)
                             .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity));
    }
}
Run Code Online (Sandbox Code Playgroud)

哪个设置Key为生成数据库,但我找不到任何方法来从约定内部访问属性的表映射.


理想情况下,我希望这样的事情:

this.Types<TypeEntity>()
    .Configure(e => e.MapInheritedProperties()
    .ToTable(e.ClrType.Name));
Run Code Online (Sandbox Code Playgroud)

或者甚至对每个需要映射的属性进行这样的调用:

this.Types<TypeEntity>()
    .Configure(e => e.Property(p=>p.Key)
                     .ToTable(e.ClrType.Name));
Run Code Online (Sandbox Code Playgroud)

这两者似乎都不存在.有什么方法可以控制内部属性的映射Convention吗?


经过一番更多的研究,它看起来像有可作为更先进的约定选择IStoreModelConventionIConceptualModelConvention,但有用的文档,如何使用这些严重缺乏.几个小时用断点和观察窗口戳它们之后,我还没想出如何使用这些接口来控制列映射.


我目前的解决方案是使用反射来查找继承的所有类型TypeEntityOnModelCreating,而属性映射到正确的表.这是有效的,但我更愿意使用一个约定,如果可能的话,因为这看起来像是为了制定约定的东西.我觉得我错过了一些明显的东西.

gre*_*k40 8

据我所知,你可以在OnModelCreating你的方法中编写类型配置DbContext,它与你在问题中提到的代码非常相似.

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

    modelBuilder.Types<TypeEntity>().Configure(c =>
    {
        c.HasKey(p => p.Key);
        // probably not needed, but won't do any harm
        c.Property(p => p.Key).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        c.ToTable(c.ClrType.Name);
    });
}
Run Code Online (Sandbox Code Playgroud)

如果这种方法有任何问题,请告诉我,我将重新访问该主题.

编辑:

完全相同的原则可以应用于约定:

class TypeEntityConvention : Convention
{
    public TypeEntityConvention()
    {
        this.Types<TypeEntity>().Configure(c =>
        {
            c.HasKey(p => p.Key);
            c.Property(p => p.Key).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            c.ToTable(c.ClrType.Name);
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

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

    modelBuilder.Conventions.Add<TypeEntityConvention>();
}
Run Code Online (Sandbox Code Playgroud)