質問

C# に詳しくないプログラマとして言えば、次のような LINQ クエリの評価セマンティクスに興味があります。

var people = from p in Person
             where p.age < 18
             select p

var otherPeople = from p in people
                  where p.firstName equals "Daniel"
                  select p

仮定して Person を定義する ADO エンティティです。 age そして firstName フィールド、これはデータベースの観点からどうなるでしょうか?具体的には、 people クエリを実行してメモリ内構造を生成し、その後、 otherPeople クエリ?あるいは、 otherPeople からクエリに関するデータを取得するだけです people そして、新しいデータベースピアクエリを生成しますか?では、これらのクエリの両方を反復処理すると、いくつの SQL ステートメントが実行されるでしょうか?

役に立ちましたか?

解決

それらは構成可能です。これが可能なのは、LINQ クエリが実際には式 (データとしてのコード) であり、LINQ-to-SQL などの LINQ プロバイダーがそれを評価し、対応する SQL を生成できるためです。

LINQ クエリは遅延評価されるため (例:要素を反復処理するまで実行されません)、示したコードは実際にはデータベースに触れません。otherPeople を反復処理するまでは、SQL が生成されて実行されません。

他のヒント

はい、結果としてクエリが作成されます。これには完全な where 句が含まれます。SQL プロファイリングを有効にして、実際に試してみてください。

Linq は式ツリーを通じてこれを行います。最初の linq ステートメントは式ツリーを生成します。クエリは実行されません。2 番目の linq ステートメントは、最初の linq ステートメントで作成された式ツリーに基づいて構築されます。このステートメントは、結果のコレクションを列挙する場合にのみ実行されます。

var people = from p in Person
             where p.age < 18
             select p

翻訳すると:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName]
FROM [dbo].[Person] AS [t0]
WHERE [t0].[Age] < @p0

ここで、@p0 は 18 として送信されます。

var otherPeople = from p in people
                  where p.firstName equals "Daniel"
                  select p

翻訳すると:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName]
FROM [dbo].[Person] AS [t0]
WHERE [t0].[FirstName] = @p0

ここで、@p0 は「ダニエル」として送信されます。

var morePeople = from p1 in people
                 from p2 in otherPeople
                 where p1.PersonId == p2.PersonId
                 select p1;

翻訳すると:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName]
FROM [dbo].[Person] AS [t0], [dbo].[Person] AS [t1]
WHERE ([t0].[PersonId] = [t1].[PersonId]) AND ([t0].[Age] < @p0) AND ([t1].[FirstName] = @p1)

ここで、@p0 は 18、@p1 は「ダニエル」です。

疑わしい場合は、IQueryable で ToString() を呼び出すか、DataContext の Log プロパティに TextWriter を指定します。

people そして otherPeople タイプのオブジェクトが含まれています IQueryable<Person>.

両方を別々に反復すると、2 つのクエリが実行されます。ただ反復するだけなら otherPeople, を指定すると、2 つの where 句を使用して予期されるクエリが実行されます。

もし、するなら .ToList() の上 people そして返されたものを使用します List<Person> 2 番目のクエリでは、people ではなく、LINQ-to-Objects になり、SQL は実行されません。

この動作は遅延実行と呼ばれます。つまり、必要になるまでクエリは実行されません。実行前は、最終的なクエリを作成するために操作される式ツリーにすぎません。

これらのクエリは両方とも、最終結果にアクセスしようとするときに実行されます。DataContext オブジェクトのプロパティから生成された元の SQL を表示してみることができます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top