1

エンティティのクエリを実行し、クエリ データに多くのインクルードを追加すると、非正規化されます。
多くの行には、いくつかの列だけが異なるデータが含まれていますが、他の列には同じデータが含まれています。
ORM を使い始める前は、複数のクエリを作成し、複雑なオブジェクトを手作業で組み立てた複数の結果セットを受け取ることを好みました。最適なアプローチは、スキーマ、返されるレコードの数、エンティティの複雑さによって異なります。

EF が複雑なエンティティをインスタンス化する 2 番目の方法をサポートしているかどうか、およびこのモードを有効にする方法を知りたいです。

アップデート

より明確にするために、少し誇張します。

A100 の単純なプロパティ (文字列、整数、日付など) で構成されるエンティティがあるとします。これらのプロパティに加えて、エンティティにはエンティティの非常に大きなコレクションが含まれていますB

クエリを考えてみましょう:

context.ASet.Include("CollectionOfB");

コレクション サーバーに含まれるアイテムごとに、B は A の単純なプロパティの多くの複製を返します。

ORM を使用せずにクエリを作成しますが、ルート オブジェクトの ID のみを要求します。次に、ルート オブジェクトを照会し、その後、ルート オブジェクト ID を参照する依存関係を照会します。
次に、辞書とハッシュ セットを使用して MARS を処理し、エンティティを組み立てます。

4

1 に答える 1

2

エンティティのセットがRoot大きすぎない場合は、明示的な読み込みを試すことができます ( の構文DbContext):

var roots = context.Roots.Where(someCondition).ToList();
foreach (var root in roots)
    root.Children = context.Entry(root).Collection(r => r.Children)
        .Query().ToList();

これは、多対多の関係を含むあらゆる種類の関係で機能します。1 + N 個のクエリがあり、N が大きすぎる場合、熱心な読み込みと比較してパフォーマンスに関しておそらく逆効果になります。

Rootとの間の関係が多対多でない場合Childは、コンテキスト ( または ) の機能である Relationship Fixup を利用できますこれによりエンティティがコンテキストに読み込まれるか、コンテキストにアタッチされたときに、オブジェクト グラフが自動的に構築されます。ObjectContextDbContext

var roots = context.Roots.Where(someCondition).ToList();
var rootIds = roots.Select(r => r.Id);
context.Children.Where(c => rootIds.Contains(c.Root.Id)).Load();

Child(ここでは、逆ナビゲーション プロパティがあると想定していますRoot。)

読み込まれるエンティティの数に関係なく、これらは常に2 つのクエリです。RootRelationship Fixup は、root.Children接続されているすべてのコレクションに自動的にデータを入力するため、熱心な読み込みを使用したrootのように結果が表示されます。

var roots = context.Roots.Include("Children").Where(someCondition).ToList();

残念ながら、コレクションが大きいContains場合、メソッドは遅くなります: https://stackoverflow.com/a/8108643/270591。ただし、熱心な読み込みを使用すると、データの重複によって引き起こされるパフォーマンス ヒットよりも、特定の数までは改善される可能性があります。rootIdsrootIds

選択肢の 1 つを優先するかどうかは、テストの問題です。すべての状況に適したいずれかのオプションを使用するための一般的なアドバイスを提供することはできません.

于 2012-12-29T12:52:15.003 に答える