2016-07-25 4 views
3

私はこのようなものを使用してEFを照会した場合...フォースのIEnumerable <T> .ToArray()または.ToListを(呼び出すことなく評価する)

IEnumerable<FooBar> fooBars = db.FooBars.Where(o => o.SomeValue == something); 

IIRC、まだ結果を含んでいない背景。むしろ、必要なときに結果を得るための「方法」の表現を含んでいます。

私は.ToArray()または.ToList()

を呼び出す必要があり、結果を格納するコレクションを強制したい場合は.ToArray()または.ToList();を呼び出さずに結果を格納するためにIEnumerable<T>コレクションを強制する方法はありますか?

理由

CLRがこれを行うことが可能であるかどうかは知りませんが、基本的に私は強制的にIEnumerable<T>インターフェイスを実装、評価、コレクションを作成したいのですが、CLRによりボンネットの下に実装されています、したがって私は、インメモリ作成するために、任意のCLR機能を認識していないよので、ませList<T>またはArray<T>

は、おそらくこれは、可能ではない、IEnumerable<T>

を実装するコレクションを評価しました

提案

言ってやる例えば、私はこのような何か書くことができる:これはfooBars内のすべての項目を評価することを

foreach (var item in fooBars) { } 

注:foreachループを使用することができます

var x = IEnumerable<FooBar> fooBars = db.FooBars 
     .Where(o => o.SomeValue == something) 
     .Evaluate(); // Does NOT return a "concrete" impl such as List<T> or Array<T> 

Console.WriteLine(x.GetType().Name); 
// eg. <EvaluatedEnumerable>e__123 
+6

'.ToList()'を呼び出すと何が問題になりますか? – user3185569

+4

はい。 'Foreach'ループを使用します。 –

+1

結果は* something *に格納しなければならないので、リスト、配列またはその他のコレクション型が必要です。 –

答えて

5

.ToArray()または.ToList();を呼び出さずに結果を格納するためにIEnumerable<T>コレクションを強制する方法はありますか?

はい、それはあなたが望むもの、おそらくではありません。

IEnumerable<T> source = …; 
IEnumerable<T> cached = new List<T>(source); 

事がある、IEnumerable<T>は具体的なタイプではありません。これは、項目順序を表すインタフェース(契約)です。このインタフェースの後ろに隠れている具体的な型があります。いくつかはクエリを表すだけであり、他は実際にクエリされたアイテムをメモリに保持します。

実際に結果が物理メモリに格納されるようにシーケンスを強制的に評価する場合は、IEnumerable<T>の背後にある具体的な型が評価の結果を保持するメモリ内のコレクションであることを確認する必要があります。上記のコード例はまさにそれを行います。

+3

これは、フード以外の '.ToList()'メソッドの実際の実装であることを指摘しておく価値があります。 – user3185569

4

を結果をすぐに破棄します。同じforeachループ、または.ToArray(),.ToList()を次に実行すると、列挙体が再び評価されます。

+1

*コレクションにはOPが記述されているように*結果が含まれていますか?いいえ、foreachループを実行するたびに列挙されます。コンパイル時の型は 'IEnumerable'です(例えば' IEnumerable fooBars = db.FooBars.Where(o => o.SomeValue == something).ToList(); ' – user3185569

+0

なぜあなたはそうすることを提案しますか?何かのためにクエリを実行するには? – Sinatr

+1

@Sinatr:理論的には、クエリは副作用を伴う可能性があるため、実際には何もしないかもしれません。それにもかかわらず。 – stakx

関連する問題