2012-07-17 33 views
0

我刚刚搬到的项目有一个抽象类Product,它被选择为这样做,因为有4种儿童类型被认为是产品并共享一个公平的共同性的数量(成分之上的原因)。 Product有一个ProductType enum与它关联。我需要制作一些与Product相关的静态功能,如GetAllProducts()通过LINQ基于抽象父属性加载混凝土子类型

里面就我的问题,因为Product表只具有共性的数据,在那里,因为我需要每个ProductType打,并选择它与Product表连接自己的表信息。

该模型的后端使用EntityFramework + OData,这是我不熟悉的技术。

从数据库中获取每个子类型的完全加载数据(+与其相关的所有通用性)的正确方法是什么,即使我不知道该子类型是什么,直到我从我的linq查询?而且,假设我已经返回了这些数据,打开ProductType以通过自己的构造函数创建实际的子类型是否有意义?

回答

1

关于EF + WCF数据服务(OData是协议,WCF DS是Microsoft的OData实现)的很酷的一部分是很多这是神奇的。你不需要任何特殊的连接或其他魔法。

下面是一些代码,让你开始:(我会穿行在下面,我保证)

using System; 
using System.Data.Entity; 
using System.Data.Services; 
using System.Data.Services.Common; 
using System.ServiceModel; 

namespace Scratch.Web 
{ 
    // 4 
    [ServiceBehavior(IncludeExceptionDetailInFaults = true)] 
    // 1 
    public class ScratchService : DataService<ScratchContext> 
    { 
     static ScratchService() 
     { 
      // 2 
      Database.SetInitializer(new ScratchContextInitializer()); 
     } 

     public static void InitializeService(DataServiceConfiguration config) 
     { 
      // 3 
      config.SetEntitySetAccessRule("*", EntitySetRights.All); 
      config.SetServiceOperationAccessRule("*", ServiceOperationRights.AllRead); 
      config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3; 
      // 4 
      config.UseVerboseErrors = true; 
     } 
    } 

    public class ScratchContextInitializer : DropCreateDatabaseIfModelChanges<ScratchContext> 
    { 
     protected override void Seed(ScratchContext context) 
     { 
      base.Seed(context); 
      // 5 
      context.Products.Add(new DiscontinuedProduct 
            { 
             Name = "DP1", 
             DiscontinuedAt = DateTime.Now.AddDays(-7) 
            }); 
      context.Products.Add(new DiscountedProduct 
            { 
             Name = "DP1", 
             Discount = 3.14 
            }); 
     } 
    } 
    // 6 
    public class ScratchContext : DbContext 
    { 
     public DbSet<Product> Products { get; set; } 
    } 
    // 7 
    public abstract class Product 
    { 
     public int ID { get; set; } 
     public string Name { get; set; } 
    } 
    // 7 
    public class DiscountedProduct : Product 
    { 
     public double Discount { get; set; } 
    } 
    // 7 
    public class DiscontinuedProduct : Product 
    { 
     public DateTime DiscontinuedAt { get; set; } 
    } 
} 

快速演练:

  • 1:ScratchService是WCF数据服务在这种情况下。它继承自DataService<T>并提供DbContext(一种EF概念)作为通用类型。
  • 2:我们使用静态构造函数设置数据库初始值设定项,因为我始终修改此代码。
  • 3:我们做实体集和服务运营,以服务消费者可见的(不推荐使用*/All的方法。)
  • 4:我们启用调试(总是有用的)
  • 5:我们播种的数据库,以获取一些数据进入它
  • 6:我们为EF创建一个DbContext并将摘要类Product作为DbSet公开。 (请注意,您需要WCF DS 5或更高版本才能使用DbContext; WCF DS 5.0.1 [或5.1.0-rc1如果您很勇敢]并且EF 4.3.1可以很好地协同工作。)
  • 7:我们在根和两个派生类中创建一个具有抽象类的类结构。

注意,当EF是在玩,你按照它的规则: - 我可以有ProductId没有DataServiceKey属性和EF将使该键的实体,WCF DS会尊重 - TPT/TPH/TPC全部为EF设置 - 如果您想先从数据库中进行编码(听起来您可能会这样做),则有一个download that will help you with that

1
  var result=(
         from product in context.Products 
         join child1 in context.Child1s 
         on product.ID equals child1.ProductID 
         join child2 in context.Child2s 
         on product.ID equals child2.ProductID 
         join child3 in context.Child3s 
         on product.ID equals child3.ProductID 
         join child4 in context.Child4s 
         on product.ID equals child4.ProductID 
         where product.ID<1000 
         select new { 

             AnonTypeProduct=product, 
             AnonTypeChild1=child1, 
             AnonTypeChild2=child2, 
             AnonTypeChild3=child3, 
             AnonTypeChild4=child4, 

         }).ToList(); 
     IEnumerable<Child1> ch1list=new IEnumerable<Child1>(); 
     IEnumerable<Child2> ch2list =new IEnumerable<Child2>(); 
     IEnumerable<Child3> ch3list=new IEnumerable<Child3>(); 
     IEnumerable<Child4> ch4list=new IEnumerable<Child4>(); 
     foreach(var result in results) 
     { 
      Child1 ch1=new Child1(); 
      ch1=result.AnonTypeChild1; 
      ch1.Product=AnonTypeProduct; 
      Child2 ch2=new Child2(); 
      ch2=result.AnonTypeChild2; 
      ch2.Product=AnonTypeProduct; 
      Child3 ch3=new Child3(); 
      ch3=result.AnonTypeChild3; 
      ch3.Product=AnonTypeProduct; 
      Child1 ch4=new Child4(); 
      ch4=result.AnonTypeChild4; 
      ch4.Product=AnonTypeProduct; 
      ch1list.Add(ch1); 
      ch1list.Add(ch2); 
      ch1list.Add(ch3); 
      ch1list.Add(ch4); 
     } 

我希望这会有所帮助。但是,您可以使用“包含”方法执行此操作。我期望上下文成为ObjectContext或DBContext的对象。