2つの問題があります。
IENumerable<Data> query = MyQuery();
//Later
foreach (Data item in query) {
//Process data
}
「プロセスデータ」ループに到達するまでに、クエリは有効でなくなる可能性があります。たとえば、既に破棄されたDataContextでクエリが実行されている場合、コードは例外をスローします。クエリを作成した場所とは異なるコンテキストでクエリを処理している場合、この種のことは非常に複雑になります。
2番目の問題は、「プロセスデータ」ループが完了するまで接続が解放されないことです。これは、「プロセスデータ」が複雑な場合にのみ問題になります。これはhttp://msdn.microsoft.com/en-us/library/bb386929.aspxで言及されています:
Q.データベース接続はいつまで開いていますか?
A.通常、接続はクエリ結果を使用するまで開いたままです。すべての結果を処理するのに時間がかかり、結果をキャッシュすることに反対しない場合は、クエリにToListを適用します。各オブジェクトが1回だけ処理される一般的なシナリオでは、ストリーミングモデルはDataReaderとLINQ to SQLの両方で優れています。
そのため、これらの問題が原因で、たとえばを呼び出すなどして、クエリが実際に実行されるように奨励されていますToList()
。ただし、ジミーが示唆するように、リストをIEnumerableとして返すことを妨げるものは何もありません。
一般的なルールとして、IEnumerableの繰り返しを2回以上避けることをお勧めします。コードのコンシューマーがこのルールに従うと仮定すると、クエリを2回実行することで誰かがデータベースに2回ヒットする可能性があるとは考えていません。