6

私はこれに慣れていません。次の状況で何が起こるか興味がありますか?

var q = //MY LINQ TO SQL QUERY.Select(...)
.........
.........
var c = q.Count();
.........
.........
var x = q.Where(....).Select(....);
var y = x.ToList();//or something such that forces materialization
var d = q.Count();//same as c
var e = x.Count();
var f = y.Count();

SQL ステートメントが実際にデータベースに移動した回数は? Count() で 1 回。再び Where()? または、Linq は Count() 中に具体化したものを保持しますか?

または、Where(..) の内容にも依存しますか? データベースを再度参照している場合と、「q」/または他の.netコレクションなどの一部として取得されたものを参照しているだけの場合のように?

編集:

他のいくつかのシナリオでコードを更新しました。以下の私の答えを修正してください:

q -no db trip
c -yes, but translates to aggregate qry - select Count(*) and not a result set (as per answer below)
x -no db trip. No matter what is written in the Where(..)
y - yes
d - yes - does not *reuse* c
e - yes - select count(*) EVEN THOUGH x already materized during y
f - no db trip
4

1 に答える 1

5

呼び出すCountと、データセット全体が具体化されません。むしろ、次のようなクエリを準備して実行します

SELECT COUNT(*) FROM ...

を使用ExecuteScalarして結果を取得します。

呼び出しWhereSelectも何も実現しない場合 (qが であると仮定IQueryable)。代わりに、次のようなクエリを準備するだけです

SELECT col1, col2, ... FROM ...

しかし、その時点では実際には実行されません。GetEnumeratorを呼び出したときにのみクエリを実行しますq。これを直接行うことはめったにありませんが、次のような場合にクエリが実行されます。

var arry = q.ToArray();
var list = q.ToList();
foreach(var rec in q) ...

このクエリは 1 回しか実行されないため、複数のforeachループがあっても複数のデータベース クエリは作成されません。もちろん、(たとえば) にIQueryable基づいて新しい を作成すると、 で使用される結果セットに関連付けられないため、データベースに再度クエリを実行する必要があります。qvar q2 = q.Where(...)q

LINQPad でコードをテストしましたが、すべての分析が正しいようです。

于 2013-03-28T14:55:43.983 に答える