0

私が移動したばかりのプロジェクトにはProduct、製品と見なされ、かなりの共通性(構成上の理由)を共有する4つの子タイプがあるため、この方法で選択された抽象クラスがあります。 Product列挙型がProductType関連付けられています。Productlikeに関連付けられた静的機能を作成する必要がありますGetAllProducts()

Productテーブルには共通性データしかないため、私の問題があります。それぞれProductTypeをヒットして選択する必要があるため、テーブルに結合された独自のテーブル情報を選択しProductます。

モデルのバックエンドは、私がよく知らないテクノロジーであるEntityFramework+ODataを使用しています。

linqクエリから選択するまで、その子タイプが何であるかわからない場合でも、データベースから各子タイプの完全にロードされたデータ(およびそれに関連するすべての共通性)を取得する適切な方法は何と考えられますか?そして、そのデータが返されたとしましょう。スイッチをオンにProductTypeして、独自のコンストラクターを介して実際の子型を作成するのは理にかなっていますか?

4

2 に答える 2

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データサービスです。ジェネリック型として(EFコンセプト)を継承しDataService<T>て提供します。DbContext
  • 2:このコードは常に変更しているため、静的コンストラクターを使用してデータベース初期化子を設定します。
  • 3:エンティティセットとサービスオペレーションをサービスコンシューマーに表示します(*/Allアプローチはお勧めしません)。
  • 4:デバッグを有効にします(常に便利です)
  • 5:データベースにシードしてデータを取得します
  • 6:DbContextEFのを作成し、抽象クラスProductをとして公開しDbSetます。(使用するにはWCF DS5以降が必要であることに注意してくださいDbContext。WCFDS5.0.1[または勇気がある場合は5.1.0-rc1]とEF4.3.1は一緒にうまく機能します。)
  • 7:ルートに抽象クラスと2つの派生クラスを持つクラス構造を作成します。

EFが機能しているときは、次のルールに従うことに注意してください。-属性がProductIdなくてもDataServiceKey、EFは、WCFDSが尊重するエンティティのキ​​ーを作成します-TPT/ TPH/TPCはすべてEF設定に準拠しています-Ifデータベースから最初にコードを実行したい場合(おそらく実行しているように聞こえます)、それを支援するダウンロードがあります

于 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 に答える