Зачем использовать 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
Я помню это так:
-
IEnumerable имеет один метод GetEnumerator(), который позволяет считывать значения в коллекции, но не записывать в нее. Большая часть сложности использования перечислителя позаботилась о нас для каждого оператора в С#. IEnumerable имеет одно свойство: Current, которое возвращает текущий элемент.
-
ICollection реализует IEnumerable и добавляет несколько дополнительных свойств, наиболее используемым из которых является Count. Универсальная версия ICollection реализует методы Add() и Remove().
-
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