9

これらのLINQ式を使用した確認/説明を探しています。

var context = new SomeCustomDbContext()

// LINQ to Entities?
var items  = context.CustomItems.OrderBy(i => i.Property).ToList();

// LINQ to Objects?
var items2 = context.CustomItems.ToList().OrderBy(i => i.Property);
  1. LINQ to Entities最初の方法は、EFが渡すためのより具体的なSQLステートメントを作成し、データベースに順序付けの労力をかけることであると考えるのは正しいですか?

  2. LINQ to ObjectsLINQがToList()注文する前にコレクション全体をメモリ(列挙型?)にドラッグしてサーバー側(この場合はWebサーバー)に負担をかける2番目の方法ですか?

    この場合、L2Eが有利である状況をすぐに確認できます(たとえば、コレクションをメモリにプルする前にコレクションをフィルタリング/トリミングする)。

  3. しかし、私が知っておくべき他の詳細/トレードオフ、または「方法2」が最初の方法よりも有利である可能性がある場合はありますか?

アップデート:

EntityFrameworkを使用していないとしましょう。これは、基盤となるリポジトリ/データソースがIQueryable<T>正しく実装されている限り当てはまりますか?LINQ to Objectsそして、これらのステートメントの両方がメモリ内の操作をもたらさない場合はどうなりますか?

4

3 に答える 3

11
  1. はい。
  2. はい。
  3. はい。

ToList()呼び出しによって、linq-to-entitiesが結果を評価し、リストとして返すように強制されるのは正しいことです。ご想像のとおり、これはパフォーマンスに大きな影響を与える可能性があります。

linq-to-entitiesが、完全に単純なクエリ(のようなWhere(x => SomeFunction(x)))のように見えるものを解析する方法を理解できない場合があります。ToList()このような場合、メモリ内のコレクションを呼び出して操作する以外に選択肢がないことがよくあります。


あなたの更新に応じて:

ToList()実行を延期するのではなく、常にその前にあるすべてのものをすぐに評価するように強制します。この例を見てください:

someEnumerable.Take(10).ToList();

vs

someEnumerable.ToList().Take(10);

2番目の例では、最初の10個の要素を取得する前に、延期された作業をsomeEnumerable実行する必要があります。someEnumerableを使用してディスクからファイルを読み取るなど、労力を要する作業を行っている場合Directory.EnumerateFiles()、これはパフォーマンスに非常に大きな影響を与える可能性があります。

于 2012-12-11T19:27:23.793 に答える
3

最初の方法は、EFが渡すためのより具体的なSQLステートメントを作成し、データベースに順序付けの労力をかけるLINQ to Entitiesであると考えるのは正しいですか?

はい

2番目の方法であるLINQtoObjectsは、LINQがコレクション全体をメモリにドラッグします...注文する前に、サーバー側に負担をかけます...?

はい

しかし、私が知っておくべき他の詳細/トレードオフ、または「方法2」が最初の方法よりも有利である可能性がある場合はありますか?

方法1が不可能な場合が多くあります。通常、SQLに直接変換できない複雑なフィルターまたは並べ替え順序がある場合(または、EFが直接SQL変換をサポートしていない場合)。また、遅延ロードされたsをネットワーク経由で送信することはできないためIQueryable、結果をシリアル化する必要があるときはいつでも、最初にそれを具体化する必要がありますToList()

于 2012-12-11T19:28:17.677 に答える
0

もう1つ注意しなければならないのは、IQueryableは、(a)基盤となるプロバイダーのセマンティック推論、または(b)プロバイダーによって実装されているIQueryableメソッドのセットの量を保証しないということです。

例えば: -

  1. EFはLast()をサポートしていません。
  2. また、DateTimesの有効なT-SQLへの時間部分の比較もサポートしていません。
  3. サブクエリでFirstOrDefault()をサポートしていません。

このような状況では、データをクライアントに戻し、クライアント側でさらに評価を実行する必要があります。

また、LINQパイプラインを解析して(EFの場合)T-SQLを生成する「方法」についても理解する必要があります。そのため、効果的なT-SQLを生成するために、LINQクエリをどのように構築するかを慎重に検討する必要がある場合があります。

そうは言っても、IQueryable<>は.NETFrameworkの非常に強力なツールであり、理解する価値があります。

于 2012-12-11T20:02:04.860 に答える