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


114

Я переглянув лише кілька веб-трансляцій, перш ніж зайнятися розробкою декількох програм Entity Framework. Я дійсно не читав стільки документації, і відчуваю, що зараз страждаю за це.

Я використовую List<T>на своїх заняттях, і це чудово спрацювало.

Тепер я прочитав деяку документацію, в якій сказано, що я мав би користуватися ICollection<T>. Я змінив це, і це навіть не викликало зміни контексту моделі. Це тому, що обидва List<T>і ICollection<T>успадковують IEnumerable<T>, і саме це насправді потрібно для EF?

Однак якщо це так, то чому в документації EF не зазначено, що вона потрібна IEnumerable<T>замість ICollection<T>?

У будь-якому випадку, чи є якісь недоліки в тому, що я зробив, або я повинен це змінити?

Відповіді:


113

Entity Framework буде використовуватися, ICollection<T>оскільки він повинен підтримувати Addоперації, які не є частиною IEnumerable<T>інтерфейсу.

Також зверніть увагу , що ви були з допомогою ICollection<T>, ви просто виставляючи його в якості List<T>реалізації. List<T>приносить разом з ним IList<T>, ICollection<T>і IEnumerable<T>.

Щодо змін, експозиція через інтерфейс - хороший вибір, незважаючи на List<T>роботу. Інтерфейс визначає контракт, але не імплементацію. Реалізація може змінитися. У деяких випадках, можливо, реалізація може бути HashSet<T>, наприклад. (Це, до речі, такий розум, який ви можете використовувати для більше ніж просто Entity Framework. Доброю об'єктно-орієнтованою практикою є програмування на інтерфейс, а не на реалізацію. Впровадження може і зміниться.)


2
Отже .... просто для мене, щоб зрозуміти трохи далі - Список успадковує IList, який успадковує ICollection, який успадковує IEnumerable?
Віль

3
Так, це ланцюжок. List<T>повинен здійснити кожен з цих інтерфейсів ( IList<T>, ICollection<T>, IEnumerable<T>) з - за ієрархії успадкування. Для завершення IList<T>також підбирає не загальний IList, так ICollectionі IEnumerableінтерфейс.
Ентоні Пеграм

Дякую ... Деякі функції Ixxx все ще уникають мого розуміння! Ти маєш сенс, однак, одне останнє, що мене дратує, якщо інший Ixx успадковує IEnumerable, то як він додається до IEnumerable, якщо читається лише Inenumerable? ... Якщо вона занадто складна, не хвилюйтесь, коли у мене буде трохи часу, я спробую підпалити рефлектор!
Віль

10
Звичайні операції Linq не додають або не змінюють речі, вони просто фільтрують, групують, проектують і т. Д. Послідовності лише для перегляду вперед - це все, що необхідно для підтримки цих операцій. Якщо у вас є постачальник Linq, такий як Entity Framework, який займається збереженням даних, можливість додавання - це істотна перевага, яка вимагає інтерфейсу програми "біфітер", що і запрошує ICollection<T>сторону (і цей інтерфейс приносить разом із нею IEnumerable<T>, тому "нормальний" "Операції Linq залишаються дійсними).
Ентоні Пеграм

@AnthonyPegram: Я думаю, що категорично неправильно сказати, що всі три інтерфейси повинні бути реалізовані. Оскільки IList <T> успадковує ICollection <T>, який успадковує IEnumerable <T>, для List <T> достатньо просто реалізувати IList <T>.
CJ7

51

Вони вибрали інтерфейс, який вони зробили, оскільки він дає зрозумілу абстракцію над магічними запитами, які виконує Entity Framework під час використання Linq.

Ось різниця між інтерфейсами:

  • IEnumerable<T> є лише для читання
  • Ви можете додавати та видаляти елементи до ICollection<T>
  • Ви можете зробити випадковий доступ (за індексом) до а List<T>

З них ICollectionі IEnumerableдобре відображайте операції з базою даних, оскільки запити та додавання / видалення об'єктів - це ви можете зробити в БД.

Випадковий доступ за індексом також не відображається, оскільки для повторного запиту вам доведеться мати повторний запит, інакше кожен випадковий доступ знову запитуватиме базу даних. Крім того, для чого було б індексну карту? Номер рядка? Ви б хотіли зробити багато запитів щодо кількості рядків, і це зовсім не корисно для створення великих запитів. Тому вони просто не підтримують це.

ICollection<T> підтримується і дозволить вам запитувати та змінювати дані, тому використовуйте це.

Причина, з якої List<T>потрібно почати, полягає в тому, що реалізація EF закінчується поверненням у підсумку. Але це в кінці ланцюжка запитів, а не на початку. Тому створення ваших властивостей ICollection<T>зробить більш очевидним, що EF створює купу SQL і повертає лише List<T>в кінці, а не виконує запити для кожного рівня Linq, який ви використовуєте.


8

ICollection відрізняється від IEnumerable тим, що ви можете фактично додавати елементи до колекції, тоді як з IEnumerable ви не можете. Так, наприклад, у своїх класах POCO, ви хочете використовувати ICollection, якщо ви хочете дозволити до колекції додавати. Зробіть віртуальну ICollection вигідною і від ледачого завантаження.


1
Я хочу зрозуміти - ви можете робити ті ж самі операції (і більше!) Зі списком <T>. Чому ICollection <T>? Чому б не Список <T>? Виглядає простіше і потужніше.
monstro

Список <T> Реалізує ICollection та IEnumerable. Більше операцій, але з цим приходить більше витрат.
IronAces

4

Хоча питання було розміщено ще багато років тому, воно все ще діє, коли хтось шукає той самий сценарій.

Існує нещодавня [2015] стаття CodeProject, яка пояснює різницю у деталізації та графічному поданні із зразковим кодом . Вона не зосереджена безпосередньо на EF, але все ж сподіваюся, що вона буде кориснішою:

Список vs IEnumerable vs IQueryable vs ICollection vs IDictionary

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.