简体   繁体   English

POCO实体框架和多态性

[英]POCO entity framework and polymorphism

i use Entities Framework Code First and I've next POCO classes: 我首先使用Entities Framework Code,接下来是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; }
    }

So let the product has a simple method MakeSale which depends on ProductCategory 因此,让产品具有一个简单的方法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;
        ...         
    }
 }

But I do not like this approach, i want use OOP and have something like this: 但我不喜欢这种方法,我想使用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;
   }
}

How can I do this with Entities Framework and saving ease of use with my entities? 如何使用Entities Framework做到这一点并保存实体的易用性?

You can try to use EF Inheritance for your objects. 您可以尝试对对象使用EF继承。 It's also available in Code First - 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 它也可以在Code First中使用-http: //weblogs.asp.net/manavi/archive/2010/12/24/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-1-table -per层次结构,tph.aspx

There are 3 different approaches based on what you need: 根据您的需求,有3种不同的方法:

  1. Table per Hierarchy - when all objects are related to the same table 每个层次结构的表-当所有对象都与同一个表相关时
  2. Table per Type - when all classes can have common data in shared table, and all specific fields is mapped to another table 每个类型的表-当所有类都可以在共享表中拥有公共数据,并且所有特定字段都映射到另一个表时
  3. Table per concrete class - when all classes have own table. 每个具体类的表-当所有类都有自己的表时。 In that case common data structure will be duplicated in each table 在这种情况下,公共数据结构将在每个表中重复

You need to map your Dress, Shoes entities based on some data in OnModelCreating method. 您需要基于OnModelCreating方法中的一些数据来映射您的Dress,Shoes实体。 For example: 例如:

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

In that case when you will load them from DBContext, it will create needed type automatically: 在这种情况下,当您从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!");       
}

and then you can update data, and save Dress\\Shoes as usual Poco objects in Code first by calling SaveChanges 然后您可以更新数据,并首先通过调用SaveChanges将Dress \\ Shoes作为常规Poco对象保存在Code中

EF maps objects into tables and it's quite obvious approach, but when getting into polymorphism, well, DB is not our best friend. EF将对象映射到表中,这是很明显的方法,但是当进入多态时,DB并不是我们最好的朋友。

Notice how EF makes your entities partial classes . 注意EF如何使您的实体成为部分类 This is for you to extend them. 这是为了您扩展它们。 So, you can write your extended class and put your virtual method there, and go on and implement other derived classes. 因此,您可以编写扩展类并将虚拟方法放在此处,然后继续执行其他派生类。

So let's say this is the generated EF class: 假设这是生成的EF类:

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

Then, on another file, write the extended class under the same namespace as Entity: 然后,在另一个文件上, 在与 Entity 相同的名称空间下编写扩展类:

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

Continue with the rest of your hierarchy: 继续进行其余的层次结构:

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

This way you still have the entity framework class and you're free to extend it and even make it the base class of your hierarchy. 这样,您仍然拥有实体框架类,并且可以自由扩展它,甚至可以使其成为层次结构的基类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM