Зачем использовать ICollection, а не IEnumerable или List <T> для отношений many-many/one-many?

Я вижу это много в учебниках, с навигационными свойствами как ICollection<T>.

Является ли это обязательным требованием для Entity Framework? Могу ли я использовать IEnumerable?

Какова основная цель использования ICollection вместо IEnumerable или даже List<T>?

Ответ 1

Обычно выбор зависит от того, к каким методам вам нужен доступ. В общем - IEnumerable<> (MSDN: http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx) для списка объектов, для которых требуется только ICollection<>, ICollection<> ( MSDN: http://msdn.microsoft.com/en-us/library/92t2ye13.aspx) для списка объектов, для которых необходимо выполнить итерацию, и для изменения, List<> для списка объектов, для которых необходимо выполнить итерацию., измененный, отсортированный и т.д. (полный список см. здесь: http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx).

С более конкретной точки зрения, ленивая загрузка играет с выбором типа. По умолчанию свойства навигации в Entity Framework поставляются с отслеживанием изменений и являются прокси-серверами. Чтобы динамический прокси-сервер создавался как свойство навигации, виртуальный тип должен реализовывать ICollection.

Свойство навигации, которое представляет конец отношения "многие", должно возвращать тип, который реализует ICollection, где T - это тип объекта на другом конце отношения. - Требования к созданию POCO-прокси MSDN

Подробнее об определении и управлении отношениями MSDN

Ответ 2

ICollection<T> используется, потому что интерфейс IEnumerable<T> не позволяет добавлять элементы, удалять элементы или иным образом изменять коллекцию.

Ответ 3

Отвечая на вопрос о List<T>:

List<T> - класс; указание интерфейса обеспечивает большую гибкость реализации. Лучший вопрос: "Почему бы не IList<T>?"

Чтобы ответить на этот вопрос, рассмотрите, что IList<T> добавляет к ICollection<T>: целочисленная индексация, что означает, что элементы имеют некоторый произвольный порядок и могут быть восстановлены по ссылке на этот порядок. Это, вероятно, не имеет смысла в большинстве случаев, поскольку в некоторых контекстах, возможно, необходимо упорядочить по-разному.

Ответ 4

Есть некоторые основные различия между ICollection и IEnumerable

  • IEnumerable - содержит только метод GetEnumerator для получения Enumerator и создания цикла
  • ICollection содержит следующие методы - Add/Remove/Contains/Count/CopyTo
  • ICollection наследуется от IEnumerable
  • С ICollection вы можете изменить коллекцию, используя такие методы, как add/remove, вы не можете делать то же самое с IEnumerable.

Простая программа:

using System;
using System.Collections;
using System.Collections.Generic;

namespace StackDemo
{
    class Program 
    {
        static void Main(string[] args)
        {
            List<Person> persons = new List<Person>();
            persons.Add(new Person("John",30));
            persons.Add(new Person("Jack", 27));

            ICollection<Person> personCollection = persons;
            IEnumerable<Person> personEnumeration = persons;

            //IEnumeration
            //IEnumration Contains only GetEnumerator method to get Enumerator and make a looping
            foreach (Person p in personEnumeration)
            {                                   
               Console.WriteLine("Name:{0}, Age:{1}", p.Name, p.Age);
            }

            //ICollection
            //ICollection Add/Remove/Contains/Count/CopyTo
            //ICollection is inherited from IEnumerable
            personCollection.Add(new Person("Tim", 10));

            foreach (Person p in personCollection)
            {
                Console.WriteLine("Name:{0}, Age:{1}", p.Name, p.Age);        
            }
            Console.ReadLine();

        }
    }

    class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public Person(string name,int age)
        {
            this.Name = name;
            this.Age = age;
        }
    }
}

Ответ 5

Я помню это так:

  1. IEnumerable имеет один метод GetEnumerator(), который позволяет считывать значения в коллекции, но не записывать в нее. Большая часть сложности использования перечислителя позаботилась о нас для каждого оператора в С#. IEnumerable имеет одно свойство: Current, которое возвращает текущий элемент.

  2. ICollection реализует IEnumerable и добавляет несколько дополнительных свойств, наиболее используемым из которых является Count. Универсальная версия ICollection реализует методы Add() и Remove().

  3. IList реализует как IEnumerable, так и ICollection и добавляет целочисленный индексный доступ к элементам (что обычно не требуется, так как упорядочение выполняется в базе данных).

Ответ 6

Основная идея использования ICollection - это обеспечить интерфейс для чтения только для доступа к некоторому конечному количеству данных. Фактически у вас есть свойство ICollection.Count. IEnumerable более подходит для некоторой цепочки данных, где вы читаете до некоторой логической точки, какое-то условие, явно заданное потребителем или до конца перечисления.

Ответ 7

В прошлом я объявлял свои коллекции внутренних классов, используя IList<Class>, ICollection<Class> или IEnumerable<Class> (если статический список), в зависимости от того, придется ли мне выполнять любое из следующих действий в Метод в моем хранилище: перечислить, отсортировать/упорядочить или изменить. Когда мне просто нужно перечислить (и, возможно, отсортировать) объекты, я создаю временный List<Class> для работы с коллекцией в методе IEnumerable. Я думаю, что эта практика будет эффективной только в том случае, если коллекция будет относительно небольшой, но в целом это может быть хорошей практикой, ИДК. Пожалуйста, поправьте меня, если есть доказательства того, почему это не будет хорошей практикой.

Ответ 8

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

Если свойство навигации может содержать несколько объектов (как в отношениях "многие-ко-многим" или "один ко многим" ), его тип должен быть списком, в котором записи могут быть добавлены, удалены и обновлены, например, ICollection.

https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application