0

Entity Frameworkでは、Includeを使用して、エンティティの単一行とそれに関連するエンティティを熱心にロードできます。

たとえば、エンティティAとエンティティB、C、およびDの間に1対多の関係があると仮定します。

var a = context.A
    .Where(a => a.Id == 7)
    .Include(a => a.B)
    .Include(a => a.C)
    .Include(a => a.D)
    .Single();

ただし、このようなクエリは非効率的です。たとえば、この場合、AとB、C、およびDの結合を返す単一のSQLクエリを生成します。したがって、結果の行の幅は、4つのテーブルの合計幅にほぼ等しくなります。すべてのエントリにほぼ同じ数の列がある場合、クエリは必要な数の約4倍のペイロードを返します。より深いレベルにクエリを実行すると、生成されたSQLの効率がさらに低下する可能性があります。

効率を向上させるために、Load()メソッドで明示的な読み込みを使用できます。例えば、

var a = context.A
   .Where(a => a.Id == 7)
   .Single();    
var b = context.Entry(a).Collection(a => a.B).Load().ToList();
var c = context.Entry(a).Collection(a => a.C).Load().ToList();
var d = context.Entry(a).Collection(a => a.D).Load().ToList();

これは、以前と同じ合計行数を返す4つの個別のクエリにマップされますが、幅は4分の1です。

Breeze.jsでは、.expand()はサーバー上の.Include()にマップされます。だから私は使用します

var query = breeze.EntityQuery
            .from("A")
            .where("Id", "==", 7)
            .expand("B, C, D");

しかし、サーバー上の明示的な読み込みにマッピングされ、上記のEF Eager Loadingの例のように、より効率的なクエリが得られるBreeze.jsクエリはありますか?マージを使用してこれを実現できるかもしれませんが、その方法がわかりません。

4

1 に答える 1

0

たぶん私はあなたの質問を誤解していますが、クエリのインクルード バージョンには明示的な読み込みを使用するバージョンよりも大きなペイロードがあると言うとき、データベースからサーバーへのペイロードではなく、データベースからサーバーへのペイロードについて話していると想定しています。サーバーからそよ風クライアントへ。微風クライアントへのペイロードはどちらの方法でも同じです。

しかし、そうは言っても、明示的な Eager ローディングを本当に使用したい場合、これを行うために私が考えることができる唯一の方法は、サーバー クエリをこのように書き直して、IQueryable を返さないようにし、Eager コレクションを強制的にオンにすることです。サーバー。

[HttpGet]
public A EagerA(id) { 
    var a = context.A
      .Where(a => a.Id == 7)
      .Single();    
    var b = context.Entry(a).Collection(a => a.B).Load().ToList();
    var c = context.Entry(a).Collection(a => a.C).Load().ToList();
    var d = context.Entry(a).Collection(a => a.D).Load().ToList();
    return a;
}

これは、「where」メソッドの代わりに「withParameters」を使用するようにクライアントを変更する必要があることも意味します。

var query = breeze.EntityQuery
        .from("A")
        .withParameters( { id: 7 });

私は実際にこれをテストしていませんが、うまくいくと思います。

于 2013-03-16T02:11:54.043 に答える