EntityFramework代码优先继承与eager包含派生类

时间:2017-11-30 21:59:11

标签: c# entity-framework inheritance

我不认为使用TPH或TPT继承方法对此有影响。

我的目标是使用单个方法从数据库加载所有可能具有不同关系的混合类型的实体,具体取决于类型。

让我们采用这个代码优先模型(简单模型来表示我的问题):

public abstract class Entity
{
    public int ID { get; set; }
    public string Name { get; set; }
}

public abstract class EntityWithInfo : Entity
{
    public AdditionalInformation Info { get; set; }
}

public class DerivedEntityWithInfo : EntityWithInfo
{
}

public class DerivedEntityWithInfo2 : EntityWithInfo
{
}

public class DerivedEntityWithoutInfo : Entity
{
}

public class AdditionalInformation
{
    public int ID { get; set; }
    public int SomeProperty { get; set; }
}

Fluent API配置:

modelBuilder.Entity<Entity>()
    .HasKey(e => e.ID)
    .Map<DerivedEntityWithInfo>(m => m.Requires("Type").HasValue(1)
    .Map<DerivedEntityWithInfo2>(m => m.Requires("Type").HasValue(2)
    .Map<DerivedEntityWithoutInfo>(m => m.Requires("Type").HasValue(3);

modelBuilder.Entity<EntityWithInfo>()
    .HasRequired(e => e.Info)
    .WithRequiredPrincipal()
    .Map(e => e.MapKey("Entity_FK"));

modelBuilder.Entity<AdditionalInformation>()
    .HasKey(e => e.ID);

或视觉上: Visual

SQL模式很简单:

Table Entity with: Id, Type, Name
Table AdditionalInformation with: Id, SomeProperty, Entity_FK

现在,我希望能够做到这样的事情:

context.Entity.Where(t => t.ID = 304 || t.ID = 512).ToList();

这正确地为我提供了所有实体的列表,并且输入正确。但是,Info属性当然总是为null。禁用LazyLoading并删除虚拟强制加载它,我知道我绝对需要在那里有一个.Include(t =&gt; t.Info)行。

我知道我可以致电

context.Entity.OfType<EntityWithInfo>().Include(t => t.Info).Where(t => t.ID = 304 || t.ID = 512).ToList();

但是我只会获得EntityWithInfo派生的实体,而不是DerivedEntityWithoutInfo派生的实体。

所以让我们尝试一个联盟:

context.Entity.OfType<EntityWithInfo>().Include(t => t.Info).Cast<Entity>()
    .Union(context.Entity.OfType<DerivedEntityWithoutInfo>().Cast<Entity>())
    .Where(t => t.ID == 719 || t.ID == 402);

这不起作用,它告诉我&#34;实体不会声明导航属性信息&#34;。

而且,我想这会创建一个SQL查询的地狱。

事实上,我之所以这样做是因为一个非常古老的项目正在使用LINQ2SQL与#34; LoadWith&#34;生成滥用SQL查询的选项(在每个继承类型的连接中复制关系表)。加载单个实体比在没有层次结构的情况下加载整个数千个元素的表需要更多次。所以我试图看看移植到EntityFramework是否会生成更优化的SQL查询。

那么,有没有办法做到这一点,或者我们只是想以错误的方式做某事?这似乎是一种非常流行的方法,既可以继承,也可以在派生类上进行关系,并且可以在网上找到很多资源。

此时,任何有关如何从此数据库模型创建此对象模型的建议都将受到赞赏。感谢

1 个答案:

答案 0 :(得分:0)

现在EF Core 2.1支持此功能。现在,看看结果查询是否不是太多性能匮乏。