首先通用中间类继承映射



我已经得到了以下要求,在OO空间中工作良好,但我似乎无法让它首先使用ADO EF代码映射回DB。

我有许多产品,每个产品都有不同的方面(属性,但不是代码属性的意义)。例如,戒指会有矿物类型=黄金等方面,而钻石会有净度方面= 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的列表,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继承映射。

似乎都不起作用。生成的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");
    }
}

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

        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'没有存在于EntitySet中"IxamDataContext.Aspects"。参数实体名称:

有来自EF代码第一专业人士的想法吗?

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

也许已经太晚了,但是我建议您使用ComplexType属性,它将允许您按照自己的意愿扩展您的类型。

相关内容

  • 没有找到相关文章

最新更新