实体框架核心看不到所有子类型字段

问题描述

您好,我正在尝试使用包含单个包含派生类型重聚的具体表的EF Core派生类。

public abstract A
{
   public int Id{get;set;}
}
public B:A
{
   public string Name{get;set;}
}
public C:A
{
   public bool IsMan{get;set;}
}

public class MyContext:DBContext
{
     public DBSet<A> ATable {get;set;}
}

生成数据库时,表ATable不包含C子类型的字段。结果表仅包含A-s字段和B-s

生成的表

  1. Id
  2. Name

PS ,我需要使用某种鉴别器吗?我只希望一个表具有两个子类型的重合,并能够使用OfType Linq扩展名访问它。

解决方法

您所描述的被称为TPH(每个层次的表)继承策略,当前是EF Core唯一支持的模式。

但是,与EF6不同,EF Core不会通过反映模型装配来自动检测派生实体。这在EF6中引起了意外的副作用,因此已被删除,现在您需要在模型中明确包含派生类型(如果其他机制(如导航属性或明确的DbSet未包括)。 EF核心文档的Entity type hierarchy mapping部分对此进行了解释:

按照惯例,EF不会自动扫描基本类型或派生类型。这意味着,如果要映射层次结构中的CLR类型,则必须在模型上显式指定该类型。例如,仅指定层次结构的基本类型不会导致EF Core隐式包括其所有子类型。

因此,您需要在样本模型中获得TPH的最低要求是添加

public DbSet<B> Bs { get; set; }
public DbSet<C> Cs { get; set; }

Entity流利的API:

modelBuilder.Entity<B>();
modelBuilder.Entity<C>();