3

コレクションに一致するアイテムが1つしかないことがわかっている場合、Linqにこれを通知して、検索が見つかったときに検索を中止する方法はありますか?

私はこれらの両方が1つのアイテムを返す前に完全なコレクションを検索すると仮定していますか?

var fred = _people.Where((p) => p.Name == "Fred").First();
var bill = _people.Where((p) => p.Name == "Bill").Take(1);

編集:FirstOrDefault人々は、、またはに固執しているようですSingleOrDefault。これらは私の質問とは何の関係もありません。コレクションが空の場合、これらは単にデフォルト値を提供します。私が述べたように、私のコレクションには単一の一致するアイテムがあることを知っています。

AakashMのコメントは私にとって最も興味深いものです。私の仮定は間違っているように見えますが、その理由に興味があります。たとえば、オブジェクトへのlinqが私のサンプルコードでWhere()関数を実行している場合、その戻り値にさらに操作があることをどのようにして知ることができますか?

4

3 に答える 3

7

あなたの仮定は間違っています。LINQは、遅延実行と遅延評価を多く使用します。これが意味するのは、たとえば、を呼び出したときに、Where()実際にはコレクションを反復処理しないということです。返されるオブジェクトを反復する場合にのみ、元のコレクションを反復します。そして、それは怠惰な方法でそれを行います:必要なだけです。

したがって、あなたの場合、どちらのクエリもコレクション全体を反復処理しません。どちらも、最初の要素が見つかった時点までのみ反復処理してから停止します。

実際、2番目のクエリ(with Take())はそれも実行せず、結果を反復する場合にのみソースコレクションを反復します。

これはすべて、オブジェクトへのLINQに適用されます。他のプロバイダー(LINQ to SQLなど)は異なる動作をする可能性がありますが、少なくとも遅延実行の原則は通常も当てはまります。

于 2012-04-20T10:43:54.363 に答える
0

First()コレクション全体をスキャンすることはないと思います。最初の試合の直後に戻ります。ただし、FirstOrDefault()代わりに使用することをお勧めします。

編集:

First()との違いFirstOrDefault()(MSDNから):

First()sourceに要素が含まれていない場合、メソッドは例外をスローします。代わりに、ソースシーケンスが空のときにデフォルト値を返すには、FirstOrDefault()メソッドを使用します。

Enumerable.First

于 2012-04-20T10:15:42.083 に答える
-1

置換これ.Where(.SingleorDefault( あなたのための最初で唯一のアイテムを見つけます。

ただし、特定の番号に対してこれを行うことはできません。2つのアイテムが必要な場合は、コレクション全体を入手する必要があります。

ただし、時間を気にする必要はありません。データベース接続を開き、クエリを確立する際に最も多くの労力が使用されます。クエリの実行にはそれほど時間はかからないので、クエリを途中で停止する本当の理由はありません:-)

于 2012-04-20T10:15:10.263 に答える