0

我刚刚搬到的项目有一个抽象类Product,之所以选择这样做是因为有 4 种子类型被认为是一种产品并且具有相当多的共性(组合的原因)。 Product有一个ProductType与之关联的枚举。我需要制作一些与Productlike相关的静态功能GetAllProducts()

这是我的问题,因为该Product表只有共性数据,因为我需要每个ProductType都点击并选择它自己的表信息与Product表连接。

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

什么被认为是从数据库中获取每个子类型的完全加载数据(以及与之相关的所有共性)的适当方法,即使在我从 linq 查询中选择它之前我不知道该子类型是什么?ProductType而且,假设我返回了该数据,通过它们自己的构造函数创建实际的子类型是否有意义?

4

2 回答 2

1

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

这里有一些代码可以帮助您入门:(我保证,我会在下面介绍它。)

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并将抽象类公开ProductDbSet. (请注意,您需要 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 设置 - 如果你想先从数据库中做代码(听起来你可能会这样做),有一个下载可以帮助你

于 2012-07-17T16:10:56.670 回答
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);
        }

我希望这将有所帮助。但是,您可以使用 Include 方法来执行此操作。我希望上下文是 ObjectContext 或 DBContext 的对象。

于 2012-07-17T13:25:22.053 回答