【发布时间】:2017-09-16 00:23:48
【问题描述】:
我有一个类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)));
}
}
这很好用,但非常重复。我必须记住为从TypeEntity 继承的每种类型创建一个配置类,设置键,并映射继承的属性。这似乎是自定义 Convention 的理想案例。
我创建了一个TypeEntityTpcConvention Convention 如下:
class TypeEntityTpcConvention : Convention
{
public TypeEntityTpcConvention()
{
this.Types<TypeEntity>()
.Configure(e => e.Property(p => p.Key)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity));
}
}
这可以将Key 设置为数据库生成,但我找不到任何方法可以从约定内部访问属性的表映射。
理想情况下,我希望是这样的:
this.Types<TypeEntity>()
.Configure(e => e.MapInheritedProperties()
.ToTable(e.ClrType.Name));
甚至对需要映射的每个属性都进行这样的调用:
this.Types<TypeEntity>()
.Configure(e => e.Property(p=>p.Key)
.ToTable(e.ClrType.Name));
似乎都不存在。有什么方法可以让我从Convention 内部控制属性的映射?
经过一些额外的研究,似乎有更高级的约定选项可用,如 IStoreModelConvention 和 IConceptualModelConvention,但是关于如何使用这些的有用文档严重缺乏。在用断点和监视窗口浏览了几个小时后,我还没有弄清楚如何使用这些接口控制列映射。
我目前的解决方案是使用反射在OnModelCreating 中查找从TypeEntity 继承的所有类型,并将属性映射到正确的表。这行得通,但如果可能的话,我更喜欢使用约定,因为这看起来确实像是约定的类型。我觉得我错过了一些明显的东西。
【问题讨论】:
-
问题不在于获取类的名称,而是
.ToTable(或其他允许我将属性重定向到不同表的东西)似乎在上下文中不存在Convention. -
啊……我误会了。我会删除评论。
-
我有一个解决方案。这不完全是一个约定,但它确实自动适用于您指定的所有类型(即您不必为每个实体添加新的配置行)。如果你有兴趣,我可以发帖。
-
您真的需要 TPC 而不仅仅是基类层次结构吗?因为 TPC 的唯一好处是自动多态(联合)查询。
-
@IvanStoev 我相信是的。 TPH 会将所有内容存储在一个表中。我希望来自
TypeEntity的所有内容都在自己的、完全独立的、单独的表中。子类实际上彼此无关。我使用基类只是因为每个都有完全相同的架构。
标签: c# entity-framework entity-framework-6