4

我尝试使用实体框架以 TPC 样式映射一些类,但出现以下错误:

错误:无法按照定义映射类型“A”,因为它映射了使用实体拆分或其他继承形式的类型的继承属性。要么选择不同的继承映射策略以便不映射继承的属性,要么更改层次结构中的所有类型以映射继承的属性并且不使用拆分。

当我使用以下类时会发生此错误:

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 继承)时,错误消失了。这是否意味着无法创建此映射,或者我只是错过了什么?

编辑:

类的属性:

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; }
}
4

2 回答 2

7

EF 4.3.1 和更早版本会出现此错误,但 EF 4.4 和 EF 5.0 不会出现此错误。(EF 4.4 实际上是 EF 5.0,但使用 .NET 4.0 作为目标平台。)

但是:仅当您将抽象类用作模型中的实体时才会发生错误,这意味着

  • 你要么DbSet在你的上下文类中有他们的 s ,比如

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

  • 或者您BaseEntityTestX在另一个(具体)实体类型中使用其中一个作为导航属性

你需要这些吗?

DbSet<BaseEntityTestX>只有当您真的想查询其中一个抽象实体时,在您的上下文中使用 a 才有意义,例如:

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

结果当然是从 继承的具体实体的列表BaseEntityTest,但它可以是不同类型的混合,例如 some As 和 some Bs。你需要这样的查询吗?还是您只想查询一些具体对象:

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

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

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

如果您将 TPC 映射扩展到基类,该错误也会消失:

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

但它会为那些对我来说似乎没有意义的抽象实体创建表。

于 2012-11-29T17:14:40.953 回答
3

在 EF6.0 中,它发生的时候

EntityTypeConfiguration'<'YourBaseClass'>'

没有详细说明您的所有派生类

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

如果汇编中只有一个派生类没有像这样配置,那么你会得到这个异常

于 2014-06-25T12:04:50.000 回答