抽象类型X没有映射的后代,因此无法映射

时间:2015-03-22 17:48:37

标签: c# entity-framework

我有以下型号:

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 当通用基类不是抽象时也是同样的问题。

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>();
}