ADO EF代码第一类通用中间类继承映射 [英] ADO EF Code First Generic Intermediate Class Inheritance mapping

查看:158
本文介绍了ADO EF代码第一类通用中间类继承映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



正如您所看到的那样,我想要一个增长我的系统的动态方式。



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

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

它有一个ProductAspect列表,它是所有方面的基类向前移动:

  public class ProductAspect 
{
public int id {get;组; }
public string AspectName {get;组; }
}

然后,我继承了ProductAspect,使用通用的方式使我成为具体的(强类型)关于我的Aspect值:

  public abstract class ProductAspect< T> :ProductAspect 
{
public T AspectValue {get;组; }
}

然后我创建一些可以让我装饰我的产品的方面: / p>

  public class StringAspect:ProductAspect< string> {}; 
public class DecimalAspect:ProductAspect< decimal> {};
public class ImageAspect:ProductAspect< byte []> {};

然后我给DbContext一个尝试,并尝试过TPH和TPC继承映射。



似乎没有工作。获取生成的DB模型不会从Aspect Table创建StringAspect或DecimalAspect表的foriegn键。

  public class IxamDataContext:DbContext 
{
public DbSet< Product>产品{get;组; }
public DbSet< ProductAspect>方面{get;组;

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 ).HasValue( DA));

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

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

 产品p = new Product(); 
p.Name =钻石;
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();

Excpetion:


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


EF代码中的任何想法首先在那里?

解决方案

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


I've got the following requirement that works well in the OO space but I can't seem to get it to map back to the DB using ADO EF code first.

I have numrous products each will have different aspects (attributes but not in the sense of code attributes). For instance ring would have aspects such as mineral type = gold etc whilst a diamond would have an aspec of clarity = VVSI1.

As you can see the products very greatly in thier composition and I want a dynamic way of growing my system.

As such I've created a product class:

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

It has a list of ProductAspect which is the base class for all aspects moving forward:

public class ProductAspect 
{
    public int id { get; set; }
    public string AspectName { get; set; }
}

I then inherit from the ProductAspect using a generic which alows me to be specific (strongly typed) about my Aspect Value:

public abstract class ProductAspect<T> : ProductAspect
{
    public T AspectValue { get; set; }
}

I then create some Aspects that will allow me to decorate my product:

public class StringAspect : ProductAspect<string> { };
public class DecimalAspect : ProductAspect<decimal> { };
public class ImageAspect : ProductAspect<byte[]> { };

I then give the DbContext a try and have tried both TPH and TPC inheritance mappings.

Neither seem to work. The DB model that get's generated doesn't create a foriegn key to the StringAspect or DecimalAspect tables from the Aspect Table.

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

Resulting in the following exception for this Seeding code:

        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();

Excpetion:

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

Any ideas from the EF code first pros out there?

解决方案

Entity framework doesn't support intermediate non mapped types in inheritance hierarchy. It means that you can't have this inheritance: A (mapped) -> B (not mapped) -> C (mapped). EF also doesn't support mapping generic types. It means that you must remove your generic intermediate class from the hierarchy and move AspectValue to derived types with correct type.

这篇关于ADO EF代码第一类通用中间类继承映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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