POCO实体框架和多态性

本文关键字:多态性 框架 实体 POCO | 更新日期: 2024-09-22 15:59:12

我首先使用实体框架代码,然后我有下一个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;
   }
}

我如何使用实体框架做到这一点,并节省实体的易用性?

POCO实体框架和多态性

您可以尝试对对象使用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

根据您的需要,有三种不同的方法:

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

您需要根据OnModelCreating方法中的一些数据映射您的连衣裙、鞋子实体。例如:

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

将Dress''Shoes作为常用的Poco对象保存在Code中

EF将对象映射到表中,这是一种非常明显的方法,但当涉及多态性时,DB并不是我们最好的朋友。

请注意EF如何使实体为分部类。这是为了让你扩展它们。因此,您可以编写扩展类并将虚拟方法放在那里,然后继续实现其他派生类。

假设这是生成的EF类:

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

然后,在另一个文件上,在与Entity:相同的命名空间下编写扩展类

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

继续使用层次结构的其余部分:

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

通过这种方式,您仍然拥有实体框架类,并且可以自由地扩展它,甚至使它成为层次结构的基类。