web-dev-qa-db-ja.com

EF ICollection VsリストVs IEnumerable Vs IQueryable

したがって、私のEFモデルには関係があり、例で見たように、それらの関係はICollectionの仮想プロパティを使用して行う必要があります。

例:

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

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

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

tHX

45
Luis Valencia

IQueryable

  • おそらく.ToList()またはforeachを実行することにより、アイテムを実際に反復処理するまでクエリは実行されません。つまり、Where()などのフィルターを追加できます。
  • IEnumerableを拡張します

IEnumerable

  • 前方のみのアイテムのリスト。アイテム0〜3を渡すことなく「アイテム4」に到達することはできません。
  • 読み取り専用リスト。追加も削除もできません。
  • それでも遅延実行を使用する可能性があります(IQueryableは依然としてIEnumerableです)。

IList

  • 全リストへのランダムアクセス
  • おそらく完全にメモリ内(遅延実行はありませんが、これを実装する正確なクラスが何を知っているのでしょうか?)
  • 追加と削除をサポート
  • IEnumerableとICollectionを拡張します

ICollection

  • IEnumerableとIListの間です。
  • IEnumerableを拡張します

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

63
Hans Kesting

EFの場合のもう1つの違いは、IEnumerableが実際にリストを列挙するまで、DBへのクエリを実行しないことです。 IListはクエリを実行し、メモリ内のアイテムを取得します。キャッシングに関して奇妙な動作をしました。 IEnumarableを追跡するとアイテムは保存されず、フェッチされていない列挙が保存され、キャッシュを呼び出して何らかの目的で列挙をフェッチするたびに、DBに移動してクエリが実行されるため、キャッシュは役に立ちませんでした。ただし、列挙のToList()はアイテムをフェッチし、キャッシュにアイテムを保存したため、このために1回だけDBにトリップします。この投稿で詳細を確認してください: http://www.dailycode.info/BlogV2/post/entityframework-adding-ienumerable-to-cache

1
Mark