42

したがって、私のEFモデルは関係を持ち、例に見られるように、これらの関係はICollectionの仮想プロパティで行う必要があります。EF ICollection対リストVs IEnumerable対IQueryable

例:

public class Task 
    { 
     public int Id { get; set; } 
     public string Description { get; set; } 
     public virtual ICollection<SubTask> { get; set; } 
    } 

私は遅延実行を防ぐためのIEnumerableを使用する必要があることをどこかで読ん、正しいということでしょうか?つまり、私のDALメソッドがIEnumerableを返してもIQueryableが返された場合、その時点でSQLが実行され、Webページの.TOListを呼び出す時点では実行されません。

だから、ベストプラクティスは何ですか?私は何を返すべきですか? IEnumerable、List?、IList、ICollection?

THX

+0

私は '仮想'が延期されているかどうかに責任があると思いましたが、間違っているかもしれません。 – mfussenegger

+0

@mfussenegger virtualは、オーバーライド可能な宣言でのみ使用されます –

答えて

60

IQueryable:あなたは本当に多分.ToList()またはforeachを行うことによって、アイテムを反復処理するまで

  • クエリが実行されていません。つまり、Where()のようなフィルタを追加できます。
  • IEnumerableを

IEnumerableを拡張:

  • アイテムの前方のみのリストを。アイテム0-3を渡さずに「アイテム4」に入ることはできません。
  • 読み取り専用リストに追加することも、そこから削除することもできません。
  • 遅延実行を使用することもできます(IQueryableは依然としてIEnumerableです)。

IList:(?いいえ遅延実行が、正確なクラスはそれがこれを実装して何をするか知っている)

  • ランダムメモリでおそらく完全なリスト
  • へのアクセス
  • は、追加サポート除外する方法
  • IEnumerableとICollectionを拡張します。

ICollection

  • IEnumerableとIListの間です。
  • "最善" とは何のIEnumerable

を拡張し、あなたの要件によって異なります。通常、IEnumerableはアイテムを表示したいだけの場合は「十分」ですが。少なくとも常に、汎用バリアントを使用してください。

+3

ナビゲーションプロパティをIEnumerable として公開すると、コレクションにアイテムを追加できなくなります。 –

+4

良いブレークダウン。例外実行に関しては、IEnumerable(他のすべての型が派生している)で.GetEnumeratorを呼び出すまで、クエリは形成されません。 IQueryable以外のものを使用すると、すべての結果がクライアントに送られ、フィルタはデータベースレベルで適用されるのではなく、フィルタリングされます。 GetEnumeratorが適切なTSQLを生成するために使用する式ツリーを保持するには、IQueryableが必要です。 –

+1

も参照してくださいhttp://stackoverflow.com/a/10113331/870291 – dotNETbeginner

1

EFの場合の別の違いは、実際にリストを列挙するまでIEnumerableがDBへのクエリを実行していないことです。 IListはクエリを実行し、メモリ内の項目をフェッチします。私はキャッシュで奇妙な動作をしました。 IEnumarableをチャタリングすると項目が格納されるのではなく、むしろ、キャッシュを呼び出して何らかの目的のために列挙をフェッチするたびに、データベースに移動してクエリを実行するので、キャッシュは役に立たなくなりました。しかし、列挙型のToList()はアイテムを取り出し、キャッシュにアイテムを格納していました。このポストでもっと見つけてください:http://www.dailycode.info/BlogV2/post/entityframework-adding-ienumerable-to-cache

関連する問題