2011-01-09 8 views
5

したがって、TPT(テーブルごとの種類)の継承を実装するとき、MicrosoftのEntity Frameworkに存在する基本的なフロアを発見するのは最後の人です。エンティティフレームワークの種類ごとのパフォーマンス

3つのサブクラス、20個以上のカラムと10個のカラムからなる基本テーブル/クラスでプロトタイプを構築したところ、すべてが美しく動作し、私はアプリケーションの残りの部分について概念。今では、他の20のサブタイプとOMGを追加する時が来ています。基本クラスのフィールドにアクセスすることにのみ関心があるにしても、単純なselectで生成されるSQLを探し始めました。

This pageには、問題の素晴らしい説明があります。

は、誰もが どのの回避策は、それは私が持っていないことを意味しますがあり、TPTおよびEFを使用して生産に入った: a)は私が達成しようとするすべてのものに反するTPH(へのスキーマ変換、私のDBデザイン - urrrgghh!)? b)別のORMで書き直しますか?

私はそれを見て、私はEF(おそらくEFExtensionsを使用して)内のストアドプロシージャへの参照を追加することができる必要があります。 SP内のモンスターUNION/JOINは、コールが行われるたびにSQLが生成されるのを防ぎます。何かをするつもりはないが、あなたはそのアイデアを得る。

私が見つけたキラーは、ベーステーブルにリンクされているエンティティのリストを選択しているときです(ただし、選択しているエンティティはサブクラステーブルではありません).PKでフィルタリングしたい私がx=>x.BaseClass.PK == 1を使用してフィルタリングして他のプロパティにアクセスできるようにするには.Include("BaseClassTableName")を実行しますが、ここでもマザーSQL生成を実行します。

3.5 SP1がインストールされた.net 2.0ランタイムに限定されているため、EF4を使用することはできません。

誰もこの混乱から抜け出す経験はありますか?

+1

私は前EF4のために話すことはできませんが、その中で文をブログ「表・パー・タイプの継承が100%である。

次のような)(付属してコンパイルクエリを使用することができます使用できません。少なくともEF4ではちょっとばかげている。いくつかのパフォーマンスの問題はありますが、20のサブタイプがある場合は、正しいデータベース正規化を実行したことを確認してください。それらの20のサブタイプは、別々の親エンティティに分割できませんか? – RPM1984

+2

他のORMが問題なくTPTデザインを処理しているようです。ブログに関しては、タイプが多いデータベース/クラス設計を実装するときに、実行前にSQLを生成するのに要する時間が数分を超えていると、私はその文をバックアップするだけで十分だと言いますプロダクション環境では使用できません。すべての車両(基本テーブル/クラス)について記憶された共通情報と、平面/電車/自動車(サブテーブル/クラス)について記憶された固有情報 - 車両を扱うのではないが、 – Tr1stan

+1

というアイデアを得て、20種類の車種が保存されています。車のサブタイプとすべての検索値に入る前に、 – Tr1stan

答えて

1

これはちょっと混乱しているようです。あなたは、TPHの話をしているが、あなたが言うとき:TSQLを持っていること

私はそれを見る方法を、私はEF(おそらくEFExtensionsを使用して)の中からストアドプロシージャへの参照を追加することができる必要があり、その私が必要とするフィールドだけを選択します。たとえEFによって生成されたモンスターのためのコードを使用していても、SP内のUNION/JOINは呼び出しが行われるたびにSQLが生成されるのを防ぎます。

これは、表ごとではなくprocを使用していますが、マッピングはTPCです...)。 EFはTPCをサポートしていますが、設計者はTPCをサポートしていません。 You can do it in code-first if you get the CTP

あなたはこのように、クエリを制限する場合は、パフォーマンス上の問題が発生しますPROCを使用してのあなたの好ましい解決策:

var q = from c in Context.SomeChild 
     where c.SomeAssociation.Foo == foo 
     select c; 

あなたがのフルスキャンを得るように、DBオプティマイザは、procの実装を通して見ることができません結果。

だから、これが結果を修正すると言う前に、その前提を再確認してください。

のカスタムSQLは、のマッピング方法を常にObjectContext.ExecuteStoreQueryと指定することができます。

ただし、これを行う前に、RPM1984が指摘しているように、デザインが継承を過剰使用しているように見えることを考慮してください。私は好きです。this quote from NHibernate in Action

[A]オブジェクトモデルの委任として継承を改造するほうがよいかもしれないかどうかを自分で判断してください。パーシステンスやORMとは無関係のあらゆる種類の理由で、複雑な継承が避けられることがよくあります。 [Your ORM]はオブジェクトとリレーショナルモデルの間のバッファとして機能しますが、オブジェクトモデルの設計時に永続性の問題を完全に無視できるわけではありません。

+0

ありがとうクレイグ、私は最後の手段としてTPHを指していました - 私が実際に達成しようとしているのはTPTです - 私は1つの基本クラス/テーブルと1つのレベルのサブクラス/テーブルを複雑な継承。しかし、おそらく、あなたは私のクラスデザインの幅があまりにも広く(〜23のサブクラス)複雑であることを指しているでしょうが、私はこれらのクラスを永続させるきれいな方法の周りに頭を浮かべているようには見えません。 – Tr1stan

+0

ああ、私はObjectContext.ExecuteStoreQueryを使ってあなたの提案に代わるものとしてクエリするSPメソッドを指していました - もう一度、賢明な人々があなたに指摘してくれたことをぼんやりと逃したことを期待していました。 – Tr1stan

2

私たちはこの同じ問題を抱えており、DALをEF4からLLBLGenに移植することを検討しています。一方

、我々は痛みのいくつかを軽減するためにコンパイルされたクエリを使用しました:

Compiled Queries (LINQ to Entities)

この戦略は、巨大なクエリを防ぐことはできませんが、時間が、それは(クエリを生成するのにかかりますそれは巨大になり得る)は一度だけ行われる。

static readonly Func<AdventureWorksEntities, int, Subcomponent> subcomponentWithDetailsCompiledQuery = CompiledQuery.Compile<AdventureWorksEntities, int, Subcomponent>(
     (ctx, id) => ctx.Subcomponents 
      .Include("SubcomponentType") 
      .Include("A.B.C.D") 
      .FirstOrDefault(s => s.Id == id)); 

    public Subcomponent GetSubcomponentWithDetails(int id) 
    { 
     return subcomponentWithDetailsCompiledQuery.Invoke(ObjectContext, id); 
    } 
関連する問題