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

Hug*_*ugo 6 generics mapping inheritance entity-framework entity-framework-4.1

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

我有数量的产品,每个都有不同的方面(属性但不是代码属性).例如,环将具有诸如矿物类型=金等等方面,而钻石将具有清晰度= VVSI1的aspec.

正如你可以在他们的作品中看到非常大的产品,我想要一种增长我的系统的动态方式.

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

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; } }
}
Run Code Online (Sandbox Code Playgroud)

它有一个ProductAspect列表,它是所有方面的基础:

public class ProductAspect 
{
    public int id { get; set; }
    public string AspectName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后,我继承了ProductAspect,使用了一个泛型,它让我对我的Aspect Value具体(强类型):

public abstract class ProductAspect<T> : ProductAspect
{
    public T AspectValue { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后我创建一些Aspects,允许我装饰我的产品:

public class StringAspect : ProductAspect<string> { };
public class DecimalAspect : ProductAspect<decimal> { };
public class ImageAspect : ProductAspect<byte[]> { };
Run Code Online (Sandbox Code Playgroud)

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

似乎都没有用.生成的DB模型不会从Aspect Table创建StringAspect或DecimalAspect表的foriegn键.

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

导致此种子代码的以下异常:

        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();
Run Code Online (Sandbox Code Playgroud)

错误时抛出:

EntityType'IxamDataContext.Aspects'中不存在EntityType'StringAspect'.参数名称:实体

来自EF代码的任何想法首先在那里推出?

Lad*_*nka 4

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