5

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エンティティであるとすると、データベースの観点からこれは何をしますか?具体的には、クエリを実行してメモリ内構造を生成し、それをクエリによってクエリしますか?または、クエリに関するデータをプルしてから、新しいデータベースピアクエリを生成するだけの構造でしょうか。したがって、これらのクエリの両方を繰り返した場合、いくつのSQLステートメントが実行されますか?agefirstNamepeopleotherPeopleotherPeoplepeople

4

5 に答える 5

12

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

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

于 2008-09-18T01:34:46.627 に答える
4
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 は "Daniel" として送信されます

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 を指定します。

于 2008-09-18T04:22:04.570 に答える
3

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

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

于 2008-09-18T01:35:16.233 に答える
1

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

両方を別々に繰り返すと、2 つのクエリが実行されます。のみを反復処理するotherPeopleと、2 つの where 句を使用して、予想されるクエリが実行されます。

2 番目のクエリで返されたものを people の代わりに使用すると、それは LINQ-to-Objects になり、SQL は実行されませ.ToList()peopleList<Person>

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

于 2008-09-18T01:33:11.700 に答える
0

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

于 2008-09-18T01:33:54.630 に答える