entity-framework - ADO EF Code First 通用中间类继承映射

标签 entity-framework generics inheritance mapping entity-framework-4.1

我有以下要求在 OO 空间中运行良好,但我似乎无法首先使用 ADO EF 代码将其映射回数据库。

我有无数的产品,每个产品都有不同的方面(属性,但不是代码属性意义上的)。例如,戒指将具有诸如矿物类型 = 黄金等方面,而钻石将具有净度 = VVSI1 等方面。

正如您可以在它们的组合中看到非常多的产品,我想要一种动态的方式来发展我的系统。

因此,我创建了一个产品类:

public class Product
{
    public int id { get; set; }
    public string Name { get; set; }
    private List<ProductAspect> aspects = new List<ProductAspect>();
    public List<ProductAspect> Aspects { get { return aspects; } set { aspects = value; } }
}

它有一个 ProductAspect 列表,它是所有方面向前发展的基类:
public class ProductAspect 
{
    public int id { get; set; }
    public string AspectName { get; set; }
}

然后我使用泛型从 ProductAspect 继承,这使我能够对我的 Aspect 值进行特定(强类型化):
public abstract class ProductAspect<T> : ProductAspect
{
    public T AspectValue { get; set; }
}

然后我创建了一些可以让我装饰我的产品的方面:
public class StringAspect : ProductAspect<string> { };
public class DecimalAspect : ProductAspect<decimal> { };
public class ImageAspect : ProductAspect<byte[]> { };

然后我尝试了 DbContext,并尝试了 TPH 和 TPC 继承映射。

两者似乎都不起作用。 get 生成的 DB 模型不会从 Aspect 表创建 StringAspect 或 DecimalAspect 表的外键。
public class IxamDataContext : DbContext
{
    public DbSet<Product> Products { get; set; }
    public DbSet<ProductAspect> Aspects { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        AspectMapping(modelBuilder);
    }

    private void AspectMapping(DbModelBuilder mb)
    {
        //TPH
        //mb.Entity<ProductAspect>()
        //    .Map<StringAspect>(m => m.Requires("type").HasValue("sa"))
        //    .Map<DecimalAspect>(m => m.Requires("type").HasValue("da"));

        //TPC
        //mb.Entity<StringAspect>().ToTable("StringAspect");
        //mb.Entity<DecimalAspect>().ToTable("DecimalAspect");
    }
}

导致此 Seeding 代码出现以下异常:
        Product p = new Product();
        p.Name = "Diamond";
        p.Aspects.Add(new StringAspect() { AspectName = "History", AspectValue = "Old and long" });
        p.Aspects.Add(new DecimalAspect() { AspectName = "Weight", AspectValue= 96.5M });


        context.Products.Add(p);
        context.SaveChanges();

异常:

EntityType 'StringAspect' does not exist in the EntitySet 'IxamDataContext.Aspects'. Parameter name: entity



来自 EF 代码的任何想法首先是专业人士吗?

最佳答案

Entity Framework 不支持继承层次结构中的中间非映射类型。这意味着您不能拥有这种继承:A(映射)-> B(未映射)-> C(映射)。 EF 也不支持映射泛型类型。这意味着您必须从层次结构中删除您的通用中间类并移动 AspectValue到具有正确类型的派生类型。

关于entity-framework - ADO EF Code First 通用中间类继承映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5776635/

相关文章:

c# - Entity Framework 包括性能不佳

java - 什么是 LinkedHashMap<k, v>?

java - Intellij 给出了奇怪的错误。 Java 泛型问题

java - java中类的继承

c++ - 什么是对象切片?

asp.net-mvc - ASP.NET MVC - 服务层 - 业务层 - 数据层 (EF) - SQL DB::数据传输?

c# - LINQ to Entities 中的多对多选择

c# - LINQ to Entities 无法识别方法 'get_Day()' 方法

Java:无法修复需要 java.util.Collection<?扩展 java.lang.String>

c++ - 有没有办法将抽象对象转换给它的 child ?