Почему не использовать ICollection и IEnumerable или список на много-много один-много отношений?


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

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

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

8 290

8 ответов:

обычно то, что вы выбираете, будет зависеть от того, какие методы вам нужен доступ. В общем - 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 поставляются с отслеживанием изменений и являются прокси-серверами. Для того чтобы динамический прокси был создан как свойство навигации, виртуальный тип должны реализовать ICollection.

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

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

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

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

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

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

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

  • IEnumerable - содержит только метод GetEnumerator, чтобы получить перечислитель и сделать цикл
  • 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;
        }
    }
}

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

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

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

  2. ICollection реализует IEnumerable и добавляет несколько дополнительных свойств, большинство из которых используют это граф. Общая версия ICollection реализует методы Add() и Remove ().

  3. IList реализует как IEnumerable, так и ICollection.

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

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

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

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