2

私の理解では、次のコードです。

IQueryable<Things> things = dataContext.Things.Take(10);
if (fromDate > new DateTime(1980, 1, 1))
    things = things.Where(a => a.InsertedDate > fromDate);
if (toDate < defaultDate)
    things = things.Where(a => a.InsertedDate < toDate);

次のようなクエリになります(日付が条件を通過すると仮定します):

select top 10 [fields] from things
where inserteddate > '1/8/2010'
    and inserteddate < '1/12/2010'

手順を踏んで、2 つの Where() ステートメントが設定されていることを確認しましたが、things.ToList() を呼び出すと、クエリが取得されます。

select top 10 [fields] from things

実際のクエリに組み込まれている 2 つの場所が実行されないのはなぜですか?

4

2 に答える 2

4

あなたのコードは間違っています。への呼び出しは、Queryable.Take必要なクエリを取得するために最後にある必要があります。

IQueryable<Things> things = dataContext.Things;

if (fromDate > new DateTime(1980, 1, 1))
{
    things = things.Where(a => a.InsertedDate > fromDate);
}

if (toDate < defaultDate)
{
    things = things.Where(a => a.InsertedDate < toDate);
}

things = things.Take(10);

最初に呼び出すTakeと、データベース全体から上位 10 要素が検索され、次にこれらの 10 項目のみの Where 原因が評価されます。通常、結果には 10 個未満の要素が含まれます。

間違ったコードは、理論的には単一のデータベース クエリとして実行される可能性があります。

SELECT [fields]
FROM
(
   SELECT TOP 10 [fields] FROM table1
) T1
WHERE inserteddate > '2010-01-08'
AND inserteddate < '2010-01-12'

この最適化は実装されていないようです。しかし、このようなクエリが頻繁に使用されるとは思えません。

于 2011-01-03T19:02:56.827 に答える
2

私の例では変数をIQueryableとしてインスタンス化していますが、実際のコードはIEnumerableとしてインスタンス化しています。IEnumerableはWhere()を異なる方法で処理し、最初の式のみがDBに対して実行され、後続のすべての式はIQueryableとは異なりメモリ内で実行されます。拡張メソッドのせいです。

于 2011-01-04T18:16:00.293 に答える