【问题标题】:Multiple inheritance with Entity Framework TPC实体框架 TPC 的多重继承
【发布时间】:2023-03-23 19:54:01
【问题描述】:

我尝试使用实体框架以 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; }
}

【问题讨论】:

  • 这是全貌吗?在我住的地方工作正常:)(VS2012,EF 5)。
  • 我用 EF 4.3.1 (VS 2012) 试过这个
  • 你的类有什么属性?

标签: entity-framework inheritance multiple-inheritance


【解决方案1】:

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

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

  • 你要么在上下文类中有DbSets,比如

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

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

你需要这些吗?

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

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

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

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

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

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

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

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

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

【讨论】:

  • 我想使用抽象类,因为我需要查询其中之一(这样我就不必为具体类型编写多个查询)。一旦我用 EF 4.4 对此进行了测试,我将立即接受您的回答。我不知道有针对 .NET 4.0 的新版本。
  • EF 4.4 似乎解决了这个问题,但在基类中引入了 [NotMapped]-Attributes 的问题,因此我无法将它用于我的项目,但答案是正确的。
【解决方案2】:

在 EF6.0 中发生这种情况时

EntityTypeConfiguration''

没有详细说明ALL你的派生类

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

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

【讨论】:

  • 这解决了我的问题。上面的代码在您的自定义 dbContext 的 OnModelCreating(DbModelBuilder modelbuilder) 函数中。添加初始迁移后 - 包管理器控制台 ->“添加迁移初始” - 创建数据库时实体框架将针对此代码执行。
猜你喜欢
  • 2016-10-28
  • 1970-01-01
  • 2016-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 2010-10-07
相关资源
最近更新 更多