¿Por qué usar ICollection y no IEnumerable o List en muchas relaciones many-one / many?

Esto lo veo mucho en tutoriales, con propiedades de navegación como ICollection .

¿Es este un requisito obligatorio para Entity Framework? ¿Puedo usar IEnumerable ?

¿Cuál es el objective principal de usar ICollection lugar de IEnumerable o incluso List ?

Por lo general, lo que elijas dependerá de los métodos a los que necesites acceder. En general, IEnumerable<> (MSDN: http://msdn.microsoft.com/en-us/library/system.collections.ienumerable.aspx ) para obtener una lista de objetos a los que solo se debe iterar, ICollection<> ( MSDN: http://msdn.microsoft.com/en-us/library/92t2ye13.aspx ) para obtener una lista de los objetos que se deben iterar y modificar, List<> para una lista de objetos que se debe iterar a través de , modificado, ordenado, etc. (Consulte aquí para obtener una lista completa: http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx ).

Desde un punto de vista más específico, la carga lenta entra para jugar con la elección del tipo. Por defecto, las propiedades de navegación en Entity Framework vienen con seguimiento de cambios y son proxies. Para que el proxy dynamic se cree como una propiedad de navegación, el tipo virtual debe implementar ICollection .

Una propiedad de navegación que representa el extremo “muchos” de una relación debe devolver un tipo que implementa ICollection, donde T es el tipo de objeto en el otro extremo de la relación. – Requisitos para crear POCO Proxies MSDN

Más información sobre la definición y administración de relaciones MSDN

ICollection se usa porque la IEnumerable no proporciona ninguna forma de agregar elementos, eliminar elementos o modificar la colección.

Respondiendo a su pregunta sobre List :

List es una clase; la especificación de una interfaz permite una mayor flexibilidad de implementación. Una mejor pregunta es “¿por qué no IList ?”

Para responder a esa pregunta, considere lo que IList agrega a ICollection : indexación entera, lo que significa que los artículos tienen un orden arbitrario, y pueden recuperarse por referencia a ese orden. Esto probablemente no sea significativo en la mayoría de los casos, ya que es probable que los artículos tengan que ordenarse de manera diferente en diferentes contextos.

Hay algunas diferencias básicas entre ICollection e IEnumerable

  • IEnumerable : contiene solo el método GetEnumerator para obtener Enumerator y hacer un bucle
  • ICollection contiene los siguientes métodos: Agregar / Quitar / Contiene / Cuenta / Copiar a
  • ICollection se hereda de IEnumerable
  • Con ICollection puedes modificar la colección usando los métodos como agregar / eliminar, no tienes la libertad de hacer lo mismo con IEnumerable.

Progtwig simple:

 using System; using System.Collections; using System.Collections.Generic; namespace StackDemo { class Program { static void Main(string[] args) { List persons = new List(); persons.Add(new Person("John",30)); persons.Add(new Person("Jack", 27)); ICollection personCollection = persons; IEnumerable 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; } } } 

La idea básica de usar ICollection es proporcionar una interfaz para el acceso de solo lectura a una cantidad finita de datos. De hecho, tiene una propiedad ICollection.Count . IEnumerable es más adecuado para algunas cadenas de datos donde se lee hasta cierto punto lógico, alguna condición especificada explícitamente por el consumidor o hasta el final de la enumeración.

Lo recuerdo de esta manera:

  1. IEnumerable tiene un método GetEnumerator () que permite leer los valores en una colección pero no escribir en ella. La mayor parte de la complejidad del uso del enumerador se ocupa de nosotros para cada enunciado en C #. IEnumerable tiene una propiedad: Current, que devuelve el elemento actual.

  2. ICollection implementa IEnumerable y agrega algunas propiedades adicionales, de las cuales la mayor parte es Count. La versión genérica de ICollection implementa los métodos Agregar () y Eliminar ().

  3. IList implementa tanto IEnumerable como ICollection.

Lo que he hecho en el pasado es declarar mis colecciones de clases internas usando IList , ICollection o IEnumerable (si está lista estática) dependiendo de si tendré que hacer cualquier cantidad de lo siguiente en un método en mi repository: enumerar, ordenar / ordenar o modificar . Cuando solo necesito enumerar (y tal vez ordenar) objetos, entonces creo una List temporal List para trabajar con la colección dentro de un método IEnumerable. Creo que esta práctica solo sería efectiva si la colección es relativamente pequeña, pero puede ser una buena práctica en general, idk. Por favor corrígeme si hay evidencia de por qué esto no sería una buena práctica.

Las propiedades de navegación generalmente se definen como virtuales para que puedan aprovechar ciertas funcionalidades de Entity Framework, como la carga diferida.

Si una propiedad de navegación puede contener múltiples entidades (como en las relaciones de muchos a muchos o uno a muchos), su tipo debe ser una lista en la que las entradas se pueden agregar, eliminar y actualizar, como 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