Entity FrameworkのICollection <T>とList <T>


114

最初にいくつかのEntity Frameworkアプリケーションの設計に取り掛かる前に、私はいくつかのWebキャストだけを見ました。あまりドキュメントを読んでいなかったので、今は苦しんでいるような気がします。

私はList<T>自分のクラスで使用していますが、うまくいきました。

今、私はいくつかのドキュメントを読みました、そしてそれは私が使うべきだったと述べていICollection<T>ます。私はこれに変更しましたが、モデルコンテキストが変更されることすらありませんでした。両方のためですList<T>ICollection<T>継承IEnumerable<T>、それが実際にEFのために必要なものでしょうか?

ただし、これが当てはまる場合、EFのドキュメントIEnumerable<T>に、代わりにEFのドキュメントに必要と記載されていないのはなぜICollection<T>ですか?

いずれにせよ、私が行ったことにマイナス面はありますか、それとも変更すべきですか?

回答:


113

Entity Frameworkは、インターフェースの一部ではない操作ICollection<T>をサポートする必要があるために使用AddIEnumerable<T>ます。

また、あなたを使用していたこと注意してくださいICollection<T>、あなたは単にそれをList<T>実装として公開しているだけです。List<T>それに伴いますIList<T>ICollection<T>IEnumerable<T>

変更については、List<T>作業を行っているにもかかわらず、インターフェイスを介して公開することをお勧めします。インターフェイスはコントラクトを定義しますが、実装は定義しません。実装変更される可能性があります。場合によっては、たとえば、実装はである可能性がありHashSet<T>ます。(ところで、これはEntity Framework以外にも使用できる考え方です。オブジェクト指向の優れた方法は、実装ではなくインターフェイスに向けてプログラミングすることです。実装は変更可能であり、今後も変更されます。)


2
だから...もう少し理解するために-リストは、IEnumerableを継承するICollectionを継承するIListを継承しますか?
WIL

3
はい、それがチェーンです。List<T>(これらのインタフェースの各々を実装する必要がありIList<T>ICollection<T>IEnumerable<T>なぜなら継承階層の)。完成のために、IList<T>また、非ジェネリック拾いIListICollectionおよびIEnumerableインタフェースを。
Anthony Pegram

ありがとう... Ixxx機能の一部はまだ理解できません!しかし、もう1つ私を困らせている最後の1つは、もう1つのIxxがIEnumerableを継承している場合、Ienumerableが読み取り専用である場合、IEnumerableにどのように追加するのでしょうか。...複雑すぎる場合は、心配しないでください。少し時間があれば、リフレクターを起動してみます。
WIL

10
通常のLinq操作では、追加や変更は行われません。単にフィルター処理、グループ化、プロジェクトなどが行われます。これらの操作をサポートするために必要なのは、転送専用、読み取り専用のシーケンスだけです。Entity Frameworkのようなデータの永続性を処理するLinqプロバイダーがある場合、追加機能はより強力なインターフェースを必要とする実質的な利点です。これはICollection<T>パーティーを招待するものであり、このインターフェースはそれをもたらすIEnumerable<T>ため、「通常の"Linq操作はまだ有効です)。
Anthony Pegram、2011年

@AnthonyPegram:3つのインターフェースすべてを実装する必要があると言うのは厳密に間違っていると思います。IList <T>はIEnumerable <T>を継承するICollection <T>を継承するため、List <T>はIList <T>を実装するだけで十分です。
CJ7 2011

51

Linqを使用するときにEntity Frameworkが実行する魔法のクエリを包括的に抽象化できるため、彼らが選んだインターフェイスを選択しました。

インターフェースの違いは次のとおりです。

  • IEnumerable<T> 読み取り専用です
  • アイテムを追加および削除できます ICollection<T>
  • あなたは(インデックスによって)ランダムアクセスを行うことができます List<T>

これらのうち、ICollectionおよびIEnumerableデータベース操作にうまくマッピング、照会とエンティティを追加/削除以来すると、DBで行う可能性がありますものです。

インデックスによるランダムアクセスも同様にマッピングされません。反復するには既存のクエリ結果が必要になるか、ランダムアクセスごとにデータベースに再度クエリが実行されるためです。また、インデックスは何にマップされますか?行番号?実行する必要のある行番号クエリはそれほど多くありません。また、より大きなクエリを構築するのにはまったく役に立ちません。したがって、彼らは単にそれをサポートしていません。

ICollection<T> がサポートされており、データのクエリと変更の両方が可能になるため、それを使用してください。

その理由は、List<T>そもそも働く最後に1を返すまでのため、EFの実装は終了です。しかし、それは最初ではなく、クエリチェーンの最後です。したがって、プロパティICollection<T>を作成すると、EFが一連のSQLを作成し、List<T>使用するLinqのレベルごとにクエリを実行するのではなく、最後にaのみを返すことがより明確になります。


8

ICollectionは、実際にアイテムをコレクションに追加できるという点でIEnumerableとは異なりますが、IEnumerableでは追加できません。たとえば、POCOクラスでは、コレクションを追加できるようにする場合は、ICollectionを使用します。ICollectionを仮想化して、遅延読み込みのメリットも活用します。


1
理解したいのですが、List <T>でも同じ操作(およびその他の操作)を実行できます。ICollection <T>を選ぶ理由 なぜList <T>ではないのですか?シンプルで強力に見えます。
monstro

List <T> ICollectionおよびIEnumerableを実装します。操作は増えますが、それに伴ってオーバーヘッドが増えます。
IronAces 2017年

4

質問は何年も前に投稿されていますが、誰かが同じシナリオを探しているときにも有効です。

最近の[2015] CodeProjectの記事では、サンプルコードを使用して詳細とグラフィカルな表現の違いを説明しています。それは直接EFに焦点を合わせていませんが、それでも大きな助けになることを願っています:

リストvs IEnumerable vs IQueryable vs ICollection vs IDictionary

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.