4

だから、ここに私のコードがあります:行ごとに比較して、IEnumerable

のメソッドの位置に注意してください。 ToList()

Customers.ToList().Where(m=>m.ID > 3).OrderByDescending(m=>m.Name).FirstOrDefault();

Customers.Where(m=>m.ID > 3).ToList().OrderByDescending(m=>m.Name).FirstOrDefault();

Customers.Where(m=>m.ID > 3).OrderByDescending(m=>m.Name).ToList().FirstOrDefault();

行ごとに見ていきましょう。

Customers.ToList().Where(m=>m.ID > 3) .OrderByDescending(m=>m.Name).FirstOrDefault()

  • .ToList() - 列挙可能
  • .Where() - 列挙可能
  • .OrderByDescending() - 列挙可能
  • .FirstOrDefault - 列挙可能

Customers.Where(m=>m.ID > 3).ToList() .OrderByDescending(m=>m.Name).FirstOrDefault()

  • .Where() - クエリ可能
  • .ToList() - 列挙可能
  • .OrderByDescending() - 列挙可能
  • .FirstOrDefault() - 列挙可能

Customers.Where(m=>m.ID > 3).OrderByDescending(m=>m.Name) .ToList().FirstOrDefault()

  • .Where() - クエリ可能
  • .OrderByDescending() - クエリ可能
  • .ToList() - 列挙可能
  • .FirstOrDefault() - 列挙可能

さて、これらの SQL を順番に示します。

SELECT [t0].[ID], [t0].[名前] FROM [顧客] AS [t0] GO

SELECT [t0].[ID], [t0].[名前] FROM [顧客] AS [t0] WHERE [t0].[ID]

SELECT TOP (1) [t0].[ID], [t0].[名前] FROM [顧客] AS [t0] WHERE [t0].[ID] > @p0 ORDER BY [t0].[名前] DESC

line1 はコレクション全体を取得してワイヤを介して渡すようですが、 line3 は 1 つのエンティティのみを取得します。

SQL 出力によると、次のように推測できます。

    line1: メモリを大量に消費するコード。より多くのデータがワイヤで渡されるため、より多くの帯域幅が必要です。
    line3: データベースを多用するコード。回線で渡されるデータが少なくなるため、必要な帯域幅が少なくなります

コードの各行間で内部的に何が起こっているのか興味があります。それらは比較的似ており、まったく同じ結果が得られます

ここで正確に何が起こっているのですか (C# とその機能の内部で?)?

4

2 に答える 2

4

.ToList()メソッドはそれを列挙可能にし、その時点でSQLを生成します。その後、LINQtoObjectsを使用しています。

したがって、たとえば、最初の行では、を呼び出し.ToList()ているため、テーブル全体を取得していますCustomers

レコード全体をメモリに取り込むため、これは良い解決策で.ToList()はありません。以前に呼び出す理由がない場合は、常にクエリの最後に呼び出してください。

于 2012-04-13T07:15:41.970 に答える
4

.Where()やのようなメソッド.OrderBy()は遅延実行を使用します。つまり、呼び出されたときに行うことは、クエリの式ツリーを変更することだけであり、クエリを実行することはありません。基になるクエリは、何かによって列挙された場合にのみ実行されます (たとえば、foreach を実行することによって)。

.ToList()一方、クエリ結果のメモリ内リストを返すことを目的としています。つまり、実際にクエリを実行させます。概念的には、次の疑似コードのようなことを行うのと似ています

foreach (item in query)
   list.add(item) 

あなたの例では、クエリはによって実行され、.ToList()その時点から、今回はメモリ内コレクションに対して新しいクエリを実行しています。

したがって、最初の例の Customers クエリは ToList() によってすぐに実行され.Where().OrderBy()Linq to objects クエリ プロバイダーを使用して新しい式ツリーを変更するだけで、この Linq to objects クエリは によって実行されますFirstOrDefault()

于 2012-04-13T07:29:22.663 に答える