ICollection <T> Vs List <T> в платформе Entity Framework

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

Я использовал List<T> в своих классах, и он отлично поработал.

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

Однако, если это так, почему в документации по EF не указано IEnumerable<T> вместо ICollection<T>?

В любом случае, есть ли недостатки в том, что я сделал, или я должен его изменить?

Ответ 1

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

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

Здесь разница между интерфейсами:

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

Из них ICollection и IEnumerable хорошо отображаются для операций с базой данных, поскольку запросы и добавление/удаление объектов - это вещи, которые вы можете сделать в БД.

Случайный доступ по индексу также не отображается, так как вам придется иметь существующий результат запроса для повторения или каждый случайный доступ будет запрашивать базу данных снова. Кроме того, на что будет ориентироваться индекс? Номер строки? Запросов числа строк не так много, и это не полезно при создании больших запросов. Поэтому они просто не поддерживают его.

ICollection<T> поддерживается и позволит вам как запрашивать, так и изменять данные, поэтому используйте это.

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

Ответ 3

ICollection отличается от IEnumerable тем, что вы действительно можете добавлять элементы в коллекцию, тогда как с IEnumerable вы не можете. Таким образом, например, в ваших классах POCO вы хотите использовать ICollection, если вы собираетесь разрешить добавление коллекции. Сделайте виртуальную виртуальную машину ICollection также полезной для ленивой загрузки.

Ответ 4

Хотя вопрос был опубликован много лет назад, он по-прежнему действует, когда кто-то ищет тот же сценарий.

Существует недавняя статья CodeProject [2015], в которой объясняется различие в деталях и графическом представлении с примером кода. Он не фокусируется непосредственно на EF, но все же надеется, что он будет иметь большую помощь:

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