使用Entity Framework TPC进行多重继承 [英] Multiple inheritance with Entity Framework TPC

查看:195
本文介绍了使用Entity Framework TPC进行多重继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用TPC样式的Entity Framework映射一些类并出现以下错误:

I tried to map some classes using Entity Framework in TPC style and got the following error:


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

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.

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

This error occurs when I use the following classes:

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映射

In the OnModelCreating method I added the following code to get the TPC mapping

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

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

When I exclude BaseEntityTest2 from the structure (so that A inherits only from BaseEntityTest instead of BaseEntityTest2) the error goes away. Does that mean that it is not possible to create this mapping or do I just miss something?

编辑:

类的属性:

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


推荐答案

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

The error occurs for EF 4.3.1 and earlier versions, but not for EF 4.4 and EF 5.0. (EF 4.4 is actually EF 5.0, but with .NET 4.0 as target platform.)

但是:只有当您将抽象类用作实体中的实体时才会出现错误模型,这意味着

BUT: The error occurs only if you are using your abstract classes as entities in your model, that means


  • 你要么拥有 DbSet s您的上下文类,例如

  • you either have DbSets for them in your context class, like

public DbSet<BaseEntityTestX> BaseEntityTestXs { get; set; }


  • 或者您有 BaseEntityTestX ,一些 modelBuilder.Entity< BaseEntityTestX>()... stuff

  • or you have some Fluent mapping for BaseEntityTestX, some modelBuilder.Entity<BaseEntityTestX>()... stuff

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

    or you are using one of the BaseEntityTestX as a navigation property in another (concrete) entity type

    你需要这些吗?

    拥有 DbSet< BaseEntityTestX> in如果你真的想查询其中一个抽象实体,你的上下文才有意义,例如:

    Having a DbSet<BaseEntityTestX> in your context would only make sense if you really want to query for one of the abstract entities, like:

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

    结果当然是从 BaseEntityTest <继承的具体实体列表/ code>,但它可以是不同类型的混合,例如一些 A s和一些 B 秒。你需要这样的询问吗?或者您只想查询一些具体对象:

    The result is of course a list of concrete entities that inherit from BaseEntityTest, but it can be a mix of different types, like some As and some Bs. Do you need such queries? Or do you only want to query for some of the concrete objects:

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

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

    In the latter case you don't need a DbSet for the abstract base classes and you don't need any inheritance mapping. You can just remove the DbSet<BaseEntityTestX> from your context class and remove the TPC mapping and your error will go away.

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

    The last point - having a navigation property to one of the abstract entities in another entity - doesn't make sense with TPC mapping. It is just not mappable to a relational database because with TPC mapping there is no table for the abstract entity, hence there is no target the foreign key relationship could refer to from the table of the concrete class that has the navigation property.

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

    The error will also disappear if you extend your TPC mapping to the base classes:

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

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

    But it will create tables for those abstract entities that don't seem to make sense to me.

    这篇关于使用Entity Framework TPC进行多重继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆