我有以下型号:
public abstract class AbstractBase { }
public abstract class AbstractBase<T> : AbstractBase where T : SomeOtherTypeBase
{
T MyProp {get; set;}
}
public class Concrete1 : AbstractBase<OtherTypeSpecializationFor1> { }
public class Concrete2 : AbstractBase<OtherTypeSpecializationFor2> { }
但是实体框架给了我错误:
抽象类型AbstractBase没有映射的后代,因此无法映射
在我看来,这不应该发生,因为AbstractBase直接继承自AbstractBase和具体继承自GenericAbstractBase的类Concrete1 / 2。这是怎么回事?
另外,出于好奇,我想知道GenericAbstractBase中T类型的属性是否会被EF保留,以防有人经过时考虑到答案。
更新1
任何人都可以确认这是EF支持吗?我见过这个post,根据罗文的回答,这应该是这样的。 谢谢
更新2 当通用基类不是抽象时也是同样的问题。
答案 0 :(得分:6)
以下是答案from the EF Team:
EDM,EF6运行时使用的基础元模型 实体类型不支持泛型。我们允许非泛型 从要添加到的常见泛型类型继承的实体类型 模型,但随着我们走上继承层次结构,我们不再寻找 一旦我们击中了一个普通的祖先。你通常使用它 能够使用完整模型对实体类型的形状进行建模 CLR方面的继承和泛型的表现力 然而,在EF方面,这导致了不相关的实体类型 被添加。
从这个角度来看,你已经定义了你的DbContext EF6运行时您要添加三种不同且不相关的实体类型: AbstractBase,Concrete1和Concrete2。所有通用类型 层次结构的中间部分已被忽略,因此EF不会 知道他们是相关的。
考虑到这个限制,你得到的例外是 预计,因为AbstractBase是抽象的,没有任何 具体的后代知道EF。如果你添加一个单独的非泛型和 直接从AbstractBase继承的具体类型,例如:
public class ConcreteFork : AbstractBase { }
您的模型应该再次有效。但是你将无法使用 MyContext.AbstractBases用于引导返回实例的查询 Concrete1或Concrete2,因为EF不知道它们是什么 相关。
顺便说一句,在EF7中我们摆脱了EDM层的实现 我们希望能够支持越来越多的场景 实际的通用实体类型。
希望这有助于解释发生了什么。
迭
答案 1 :(得分:-1)
我在CodeProject文章Spreading Inheritance Tree Mapping Across Assemblies in Code First中找到了Gil Fink提供的解决方案。
问题的解决方案是将映射添加到上下文中的所有实体。为此,您必须覆盖OnModelCreating方法并映射所有实体:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<AbstractBase>();
modelBuilder.Entity<Concrete1>();
modelBuilder.Entity<Concrete2>();
}