2012-11-24 94 views
4

多重继承我试图映射在TPC风格使用实体框架一些类,并得到了以下错误:与实体框架TPC

Error: The type 'A' cannot be mapped as defined because it maps inherited properties from types that use entity splitting or another form of inheritance. Either choose a different inheritance mapping strategy so as to not map inherited properties, or change all types in the hierarchy to map inherited properties and to not use splitting.

当我用下面的类会出现此错误:

public abstract class BaseEntityTest 
public abstract class BaseEntityTest2 : BaseEntityTest 
public abstract class BaseEntityTest3 : BaseEntityTest2 
public class A: BaseEntityTest3 // this class is the only one with a table in the db 

在OnModelCreating方法中,我添加了以下代码以获得TPC映射

modelBuilder.Entity<A>().Map(m => 
{ 
    m.MapInheritedProperties(); 
    m.ToTable("A"); 
}); 

当我从结构中排除BaseEntityTest2(因此A只从BaseEntityTest而不是BaseEntityTest2继承)时,错误消失。这是否意味着不可能创建这个映射或者我只是错过了什么?

编辑:类

属性:为EF 4.3.1及更早版本发生

public abstract class BaseEntityTest 
{ 

    [Key] 
    public Guid Id { get; set; } 

    public String Info { get; set; } 

    [Required] 
    public DateTime CreationDate { get; set; } 

    [Required] 
    public String CreationUser { get; set; } 

    [Required] 
    public DateTime ModificationDate { get; set; } 

    [Required] 
    public String ModificationUser { get; set; } 

    [ConcurrencyCheck] 
    [Required] 
    public int LockVersion { get; internal set; } 
} 

public abstract class BaseEntityTest2 : BaseEntityTest 
{ 
    [Required] 
    public string Name { get; set; } 

    public string Description { get; set; } 

} 

public abstract class BaseEntityTest3: BaseEntityTest2 
{ 

    [Required] 
    public DateTime FromDate { get; set; } 

    public DateTime ThruDate { get; set; } 
} 

public class A: BaseEntityTest3{ 
    public String Test { get; set; } 
} 
+0

这是全貌吗?在我住的地方工作得很好:)(VS2012,EF 5)。 –

+0

我试过这个使用EF 4.3.1(VS 2012) – Eggi

+0

你有什么属性在你的课堂上? –

回答

6

错误,但不能用于EF 4.4和EF 5.0。 (EF 4.4实际上是EF 5.0,但与.NET 4.0作为目标平台。)

但是:只有当您使用的是抽象类作为你的模型,这意味着

  • 实体出现的错误你要么有DbSet对于他们在你的上下文类,像

    public DbSet<BaseEntityTestX> BaseEntityTestXs { get; set; } 
    
  • ,或者你有一些流利的映射BaseEntityTestX,一些modelBuilder.Entity<BaseEntityTestX>()...东西

  • ,或者你正在使用的BaseEntityTestX作为导航性能的一个在另一个(混凝土)实体类型

你需要任何的吗?

有一个DbSet<BaseEntityTestX>在上下文只会意义,如果你真的想查询抽象实体之一,如:

List<BaseEntityTest> list = context.BaseEntityTests 
    .Where(b => b.Info == "abc").ToList(); 

结果当然是从BaseEntityTest继承具体的实体名单,但它可以是不同类型的组合,如A和某些B。你需要这样的疑问吗?或者你只是想查询一些具体的对象:

List<A> list = context.As 
    .Where(b => b.Info == "abc").ToList(); 

在后一种情况下,你不需要为抽象基类一DbSet,你不需要任何继承映射。您可以从您的上下文类中删除DbSet<BaseEntityTestX>,并删除TPC映射,您的错误将消失。

最后一点 - 对另一个实体中的某个抽象实体具有导航属性 - 对于TPC映射没有意义。它只是无法映射到关系数据库,因为使用TPC映射时,抽象实体没有表,因此没有目标可以从具有导航属性的具体类的表中引用外键关系。

modelBuilder.Entity<BaseEntityTestX>().Map(m => 
{ 
    m.MapInheritedProperties(); 
    m.ToTable("BaseEntityTestX"); 
}); 

但它会为那些似乎没有什么意义对我来说抽象实体表:如果您延长TPC映射到基类

错误也将消失。

+0

我想使用抽象类,因为我需要查询其中的一个(这样我就不必为具体类型编写多个查询)。我一接受EF 4.4的测试就会接受你的答案。我不知道有一个针对.NET 4.0的新版本。 – Eggi

+0

EF 4.4似乎解决了这个问题,但是在基类中引入了[NotMapped] - 属性的问题,所以我不能将它用于我的项目,但答案是正确的。 – Eggi

2
在EF6.0其发梗

EntityTypeConfiguration'<'YourBaseClass'>'

没有详细ALL

 this.Map<DerivedClass1>(m => 
     { 
      m.MapInheritedProperties(); 
      m.ToTable(".."); 
     }); 

派生类,如果在assembley只是一个dervied类没有配置像这样 你这个例外

+0

这解决了我的问题。上述代码出现在您的自定义dbContext的OnModelCreating(DbModelBuilder modelbuilder)函数中。在添加初始迁移 - 软件包管理器控制台 - >“添加迁移初始化”时,实体框架将在创建数据库时针对此代码执行。 –