ICollection <T> Vs List <T> im Entity Framework

114

Ich habe nur ein paar Webcasts gesehen, bevor ich mich mit dem Entwerfen einiger Entity Framework-Anwendungen befasst habe. Ich habe wirklich nicht so viel Dokumentation gelesen und ich habe das Gefühl, dass ich jetzt darunter leide.

Ich habe List<T>in meinen Klassen verwendet, und es hat großartig funktioniert.

Jetzt habe ich einige Dokumentationen gelesen und es heißt, dass ich hätte verwenden sollen ICollection<T>. Ich habe dies geändert und es hat nicht einmal eine Änderung des Modellkontexts verursacht. Liegt das daran, dass beide List<T>und ICollection<T>erben IEnumerable<T>, und das ist es, was für EF tatsächlich erforderlich ist?

Wenn dies jedoch der Fall ist, warum wird in der EF-Dokumentation nicht angegeben, dass dies IEnumerable<T>anstelle von erforderlich ist ICollection<T>?

Gibt es auf jeden Fall Nachteile bei dem, was ich getan habe, oder sollte ich es ändern?

wil
quelle

Antworten:

113

Entity Framework würde verwenden, ICollection<T>da es AddVorgänge unterstützen muss, die nicht Teil der IEnumerable<T>Schnittstelle sind.

Beachten Sie auch, dass Sie es verwendet haben ICollection<T>und es lediglich als List<T>Implementierung verfügbar gemacht haben. List<T>bringt zusammen mit ihm IList<T>, ICollection<T>und IEnumerable<T>.

Was Ihre Änderung betrifft, ist das Belichten über die Benutzeroberfläche trotz der List<T>Arbeit eine gute Wahl . Die Schnittstelle definiert den Vertrag, nicht aber die Implementierung. Die Implementierung könnte sich ändern. In einigen Fällen könnte die Implementierung HashSet<T>beispielsweise eine sein. (Diese Denkweise können Sie übrigens nicht nur für Entity Framework verwenden. Eine gute objektorientierte Praxis besteht darin, auf die Schnittstelle und nicht auf die Implementierung zu programmieren. Implementierungen können und werden sich ändern.)

Anthony Pegram
quelle
2
Also ... nur damit ich etwas weiter verstehe - List erbt IList, das ICollection erbt, das IEnumerable erbt?
Wil
3
Ja, das ist die Kette. List<T>muss jede dieser Schnittstellen (implementieren IList<T>, ICollection<T>, IEnumerable<T>) wegen der Vererbungshierarchie. Zum Abschluss, IList<T>nimmt auch die nicht-generic up IList, ICollectionund IEnumerableSchnittstellen.
Anthony Pegram
Vielen Dank ... Einige der Ixxx-Funktionen entziehen sich immer noch meinem Verständnis! Sie haben jedoch Sinn gemacht, eine letzte Sache, die mich nervt, wenn die anderen Ixx IEnumerable erben, wie wird sie zur IEnumerable hinzugefügt, wenn eine Ienumerable schreibgeschützt ist? ... Wenn es zu komplex ist, mach dir keine Sorgen, wenn ich etwas Zeit habe, werde ich versuchen, den Reflektor zu zünden!
Wil
10
Normale Linq-Operationen fügen keine Dinge hinzu oder mutieren sie, sondern filtern, gruppieren, projektieren usw. Nur vorwärtsgerichtete, schreibgeschützte Sequenzen sind alles, was zur Unterstützung dieser Operationen erforderlich ist. Wenn Sie einen Linq-Anbieter wie Entity Framework haben, der sich mit Datenpersistenz befasst, ist die Fähigkeit zum Hinzufügen ein wesentlicher Vorteil, der eine stärkere Schnittstelle erfordert, was ICollection<T>die Partei einlädt (und diese Schnittstelle bringt dies mit sich IEnumerable<T>, also das "Normale" "Linq-Operationen sind noch gültig).
Anthony Pegram
@AnthonyPegram: Ich denke, es ist absolut falsch zu sagen, dass alle drei Schnittstellen implementiert werden müssen. Da IList <T> ICollection <T> erbt, die IEnumerable <T> erbt, reicht es für List <T> aus, IList <T> einfach zu implementieren.
CJ7
51

Sie haben die Schnittstelle ausgewählt, die sie erstellt haben, da sie eine verständliche Abstraktion über die magischen Abfragen bietet, die das Entity Framework bei Verwendung von Linq ausführt.

Hier ist der Unterschied zwischen den Schnittstellen:

  • IEnumerable<T> ist schreibgeschützt
  • Sie können Elemente zu einem hinzufügen und daraus entfernen ICollection<T>
  • Sie können wahlweise (nach Index) auf a zugreifen List<T>

Von diesen ICollectionund IEnumerablegut auf Datenbankoperationen abzubilden, da das Abfragen und Hinzufügen / Entfernen von Entitäten Dinge sind, die Sie in einer Datenbank tun könnten.

Der Direktzugriff nach Index wird nicht so gut zugeordnet, da für die Iteration ein vorhandenes Abfrageergebnis erforderlich wäre, da sonst bei jedem Direktzugriff die Datenbank erneut abgefragt würde. Wem würde der Index auch zugeordnet? Zeilennummer? Es gibt nicht viele Zeilennummernabfragen, die Sie ausführen möchten, und es ist überhaupt nicht hilfreich, größere Abfragen aufzubauen. Also unterstützen sie es einfach nicht.

ICollection<T> wird unterstützt und ermöglicht es Ihnen, Daten sowohl abzufragen als auch zu ändern. Verwenden Sie diese Option.

Der Grund List<T>dafür ist zunächst, dass die EF-Implementierung am Ende eine zurückgibt. Aber das ist am Ende Ihrer Abfragekette, nicht am Anfang. Wenn Sie also Ihre Eigenschaften ICollection<T>festlegen, wird deutlicher, dass der EF eine Reihe von SQL erstellt und erst List<T>am Ende ein zurückgibt , anstatt Abfragen für jede von Ihnen verwendete Linq-Ebene durchzuführen.

Merlyn Morgan-Graham
quelle
8

ICollection unterscheidet sich von IEnumerable darin, dass Sie der Sammlung tatsächlich Elemente hinzufügen können, während dies mit IEnumerable nicht möglich ist. In Ihren POCO-Klassen möchten Sie beispielsweise ICollection verwenden, wenn Sie zulassen möchten, dass die Sammlung hinzugefügt wird. Machen Sie die ICollection virtuell, um auch vom verzögerten Laden zu profitieren.

Ralph Lavelle
quelle
1
Ich möchte verstehen, dass Sie mit List <T> dieselben Operationen (und mehr!) Ausführen können. Warum ICollection <T>? Warum nicht <T> auflisten? Sieht einfacher und leistungsfähiger aus.
Monstro
List <T> Implementiert ICollection und IEnumerable. Mehr Betrieb, aber damit verbunden ist mehr Overhead.
IronAces
4

Obwohl die Frage vor Jahren gestellt wurde, ist sie immer noch gültig, wenn jemand nach demselben Szenario sucht.

Es gibt einen kürzlich erschienenen [2015] CodeProject-Artikel, in dem der Unterschied im Detail und in der grafischen Darstellung mit Beispielcode erläutert wird . Es ist nicht direkt auf EF ausgerichtet, hofft aber dennoch, dass es eine größere Hilfe sein wird:

Liste vs IEnumerable vs IQueryable vs ICollection vs IDictionary

BiLaL
quelle