我有以下要求在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; } }
}
它有一个ProductAspect列表,它是前进所有方面的基类:
public class ProductAspect
{
public int id { get; set; }
public string AspectName { get; set; }
}
然后我继承了ProductAspect,使用了一个泛型,它让我对我的Aspect Value具体(强类型):
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 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");
}
}
导致此播种代码出现以下异常:
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'没有 存在于EntitySet中 'IxamDataContext.Aspects'。参数 name:entity
EF代码的任何想法首先在那里推出?
答案 0 :(得分:4)
实体框架不支持继承层次结构中的中间非映射类型。这意味着你不能拥有这种继承:A(映射) - &gt; B(未映射) - &gt; C(映射)。 EF也不支持映射泛型类型。这意味着您必须从层次结构中删除通用中间类,并将AspectValue
移动到具有正确类型的派生类型。
答案 1 :(得分:0)
也许是为时已晚,但我会建议你使用ComplexType attribute它可以让你按照自己的意愿扩展你的类型。