Вопрос по c#, entity-framework – Зачем использовать ICollection, а не IEnumerable или List <T> для отношений многие-многие / один-многие?

314

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

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

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

Ваш Ответ

8   ответов
388

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

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

A navigation property that represents the "many" end of a relationship must return a type that implements ICollection, where T is the type of the object at the other end of the relationship. -Requirements for Creating POCO ProxiesMSDN

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

Итак, с этим,List должно быть намного лучше, да? Jan Carlo Viray
Что касается вашего редактирования, ограничение свойства типом интерфейса связано не с памятью, а с инкапсуляцией. Рассматривать:private IEnumerable<int> _integers = new List<int> { 1, 2, 3 }; использует ту же память, что иprivate List<int> _integers = new List<int> { 1, 2, 3 };
@JanCarloViray - я склонен использоватьList много. Хотя у него больше всего накладных расходов, он обеспечивает большую функциональность.
Списки определяются в большей степени их индексаторами, чем возможностью их сортировки (наличие целочисленного индексатора облегчает сортировку чего-либо, но это не является обязательным требованием).
@TravisJ:List<T> имеетGetEnumerator() метод, отдельный от его реализацииIEnumerable<T>, который возвращает изменяемый тип структурыList<T>.Enumerator, В большинстве случаев этот тип даст немного лучшую производительность, чем автономный объект кучи. Компиляторы, которые используют перечислители утилитарного типа (как это делают и C #, и vb.net), могут использовать это при генерацииforeach код. ЕслиList<T> брошен вIEnumrable<T> передforeach,IEnumerable<T>.GetEnumerator() Метод возвращает объект, выделенный в куче, что делает оптимизацию невозможной.
76

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

List<T> инвентарьICollection<T>.
как насчет сравнения со списком & lt; T & gt ;? Jan Carlo Viray
НеуниверсальныйICollection не позволяет каким-либо образом добавлять элементы, но все еще является полезным дополнением кIEnumerable<T> потому что это обеспечиваетCount член, который обычно намного быстрее, чем перечислять все. Обратите внимание, что еслиIList<Cat> или жеICollection<Cat> передается в код, ожидающийIEnumerable<Animal>,Count() метод расширения будет быстрым, если он реализует неуниверсальныйICollection, но не если он реализует только общие интерфейсы, так как типичныйICollection<Cat> не будет реализовыватьICollection<Animal>.
6

IEnumerable has one method GetEnumerator() which allows one to read through the values in a collection but not write to it. Most of the complexity of using the enumerator is taken care of for us by the for each statement in C#. IEnumerable has one property: Current, which returns the current element.

ICollection implements IEnumerable and adds few additional properties the most use of which is Count. The generic version of ICollection implements the Add() and Remove() methods.

IList implements both IEnumerable and ICollection, and add the integer indexing access to items (which is not usually required, as ordering is done in database).

Исходя из того, что вы написали, ICollection и IList совпадают. Пожалуйста, добавьте то, что добавлено в IList, чего нет в ICollection.
ICollection VS IList, интерфейс только для IList в System.Collection, который содержит все функции IEnumerable и ICollection и дополнительные функции. В IList есть методы Insert и Remove. Оба метода принимают индекс в своем параметре. Таким образом, он поддерживает индексные операции над коллекцией.
15

IEnumerable - Contains only GetEnumerator method to get Enumerator and make a looping ICollection is containing the following methods - Add/Remove/Contains/Count/CopyTo ICollection is inherited from IEnumerable With ICollection you can modified the collection by using the methods like add/remove , you dont have the liberty to do the same with 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;
        }
    }
}
53

List<T>:

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

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

2

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

2

чтобы они могли использовать определенные функции 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-приложения

8

ICollection является интерфейсом для доступа только для чтения к некоторому конечному объему данных. На самом деле у вас естьICollection.Count имущество.IEnumerable больше подходит для некоторой цепочки данных, где вы читаете до некоторой логической точки, некоторого условия, явно указанного потребителем, или до конца перечисления.

Пока чтоICollection только для чтения, покаICollection<T> не является.

Похожие вопросы