在解决方案中跨多个项目创建TPT继承时,EF6.x是否存在问题



考虑以下场景(在代码优先的工作流中使用EF6和VS 2017)。

我有一个基本抽象实体基类(它提供了一个ID属性和一些适用于所有实体的其他属性)。

我有一个继承entitybase的联系人类。它也是抽象的,为应用程序将使用的典型业务对象(例如Customer和Supplier)提供了通用属性,并提供了诸如First和Last Name之类的内容。

最后是从Contact继承的独立的Customer和Supplier类。

如果我将所有这些组件都放在一个项目中,请添加EF Nuget包,启用迁移,然后添加一个迁移。我将获得我所期望的每种类型的表结构(Contact表以及通过外键链接到Contact表的单独的Customer和Supplier表)。满足了联系人既可以是客户又可以是供应商的业务规则。

现在,在大规模应用程序中,公共基类很可能位于一个单独的项目中,该项目包含许多不同上下文所共有的项。联系人类、客户类和供应商类很可能在它们自己的单独项目中,联系人上下文可能在其自己单独的项目中。

如果我复制该场景,然后启用并添加迁移,我最终会得到独立的Customer和Supplier类,它们有自己从Contact继承的字段副本,但没有Contacts表。商业规则马上就被打破了。

这是EF6的已知问题吗?

如果这是一个小型应用程序,我会简单地将所有内容捆绑到一个项目中(所有内容都分离到不同的文件夹中)。然而,我希望沿着代码第一行重构现有的更大的应用程序,并将各种模式分解为单独的部分,这些部分本身可能由许多项目组成,这更有意义。我很可能做错了什么,因为我仍然是从代码开始的,但如果有人遇到过这种情况,或者知道我应该如何安排组件以使其工作,我欢迎任何想法。

在这种情况下(当实体类程序集与DbContext程序集不同时),EF6基本实体发现过程似乎存在问题。

根据经验,始终公开继承根实体的多态DbSet,或使用Entity<T>()fluent API显式标识它。

因此,以下两种选择中的任何一种都可以解决问题:

public class MyDbContext : DbContext
{
// ...
public DbSet<Contact> Contacts { get; set; }
// ...
}

public class MyDbContext : DbContext
{
// ...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// ...
modelBuilder.Entity<Contact>();
// ...
}
// ...
}

最新更新