2013-12-13 139 views
2

我使用实体框架代码首先,我已经下一个POCO类:POCO实体框架和多态性

public class Product 
    {  
     public int ProductID { get; set; } 
     public int Title{ get; set; } 
     public int Price { get; set; } 

     public int ProductCategoryID { get; set; } 
     public virtual ProductCategory ProductCategory { get; set; } 
    } 

    public class ProductCategory 
    { 
     public int ProductCategoryID { get; set; }   
     public int Title{ get; set; } 
     public virtual ICollection<Product> Products { get; set; } 
    } 

因此,让产品有一个简单的方法MakeSale取决于ProductCategory

public int void GiveSale() 
{ 
    //I can do like this ... 
    switch (this.ProductCategoryID) 
    { 
     case 1: return this.Price * 0,8; 
     break; 
     case 2: return 0; 
     ...   
    } 
} 

但我不喜欢这种方法,我想用OOP并且有类似的东西:

public class Dress : Product 
{ 
    public override int void GiveSale() 
    { 
     return this.Price * 0,8; 
    } 
} 

public class Shoes : Product 
{ 
    public override int void GiveSale() 
    { 
     return 0; 
    } 
} 

如何使用实体框架来实现这一点,并保存与我的实体的易用性?

回答

3

你可以尝试使用EF继承你的对象。它也可以在代码第一次 - http://weblogs.asp.net/manavi/archive/2010/12/24/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-1-table-per-hierarchy-tph.aspx

有你所需要的基础上3点不同的方法:每一个分层

  1. 表 - 当所有的对象都与同一个表每类型
  2. 表 - 当所有的类可具有共享表的公共数据,并且所有的特定字段被映射到另一个表
  3. 每个具体表类 - 当所有类有自己的表。在这种情况下,通用数据结构将在每张表中复制

您需要根据OnModelCreating方法中的某些数据映射Dress,Shoes实体。例如:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Product>() 
      .Map<Dress>(m => m.Requires("ProductCategoryID").HasValue(1)) 
      .Map<Shoes>(m => m.Requires("ProductCategoryID").HasValue(2)); 
} 

在的时候你会从的DbContext加载它们这种情况下,它会自动创建所需的类型:

List<Product> products = dbContext.Products.ToList(); 
foreach(var product in products) 
{ 
    var sale = product.GiveSale(); 
    if (product is Dress) Console.WriteLine("It's dress!"); 
    if (product is Shoes) Console.WriteLine("It's a pair of shoes!");  
} 

,然后你可以更新数据,并保存连衣裙\鞋像往常一样波科在代码对象首先调用的SaveChanges

0

EF对象映射到表,这是相当明显的方法,但是进入多态性的时候,那么,DB是不是我们最好的朋友。

通知EF如何让你的实体部分类。这是给你的延伸。 所以,你可以编写你的扩展类,并把你的虚拟方法放在那里,继续实现其他派生类。

所以我们可以说这是生成的EF类:

public partial class Entity 
{ 
    public int ID { get; set; } 
    public string Name { get; set; } 
    ... 
} 

然后,在另一个文件,写扩展的类下相同的命名空间的实体:

public partial class Entity 
{ 
     public virtual int GiveSale() 
     { 
      return 0; 
     } 
} 

与继续休息等级:

public class Derived : Entity 
{ 
    public override int GiveSale() 
    { 
      return your calculation; 
    } 
} 

这样您仍然拥有实体框架类,并且可以自由扩展它,甚至可以将其作为层次结构的基类。