2011-10-05 24 views
80

Solo vi algunos webcasts antes de entrar de cabeza en el diseño de algunas aplicaciones de Entity Framework. Realmente no leí tanta documentación y siento que estoy sufriendo por eso ahora.ICollection <T> Vs List <T> en Entity Framework

He estado usando List<T> en mis clases, y funcionó muy bien.

Ahora he leído algunos documentos y dice que debería haber estado usando ICollection<T>. Cambié a esto, y ni siquiera causó un cambio de contexto modelo. ¿Esto se debe a que List<T> y ICollection<T> heredan IEnumerable<T>, y eso es lo que realmente se requiere para EF?

Sin embargo, si este es el caso, ¿por qué la documentación de EF no indica que se requiere IEnumerable<T> en lugar de ICollection<T>?

En cualquier caso, ¿hay algún inconveniente en lo que he hecho, o debería cambiarlo?

Respuesta

79

Entity Framework usaría ICollection<T> porque necesita admitir operaciones Add, que no son parte de la interfaz IEnumerable<T>.

También tenga en cuenta que eran usando ICollection<T>, que no eran más que exponerla como la implementación List<T>. List<T> trae consigo IList<T>, ICollection<T> y IEnumerable<T>.

En cuanto a su cambio, exponer a través de la interfaz es una buena opción, a pesar de List<T> de trabajo. La interfaz define el contrato pero no la implementación. La implementación podría cambiar. En algunos casos, quizás la implementación podría ser HashSet<T>, por ejemplo. (Esta es una mentalidad que podría usar para algo más que Entity Framework, por cierto. Una buena práctica orientada a objetos es programar hacia la interfaz y no la implementación. Las implementaciones pueden cambiar y lo harán.)

+1

Así .... sólo para mí entender un poco más lejos - Lista hereda IList, que hereda ICollection, que hereda de IEnumerable ? – wil

+1

Sí, esa es la cadena. 'List ' tiene que implementar cada una de esas interfaces ('IList ', 'ICollection ', 'IEnumerable ') debido a la jerarquía de herencia. Para completar, 'IList ' también recoge las interfaces no genéricas 'IList',' ICollection' e 'IEnumerable'. –

+0

Gracias ... ¡Algunas de las características de Ixxx aún escapan a mi comprensión! Sin embargo, tiene sentido una última cosa que me molesta, si las otras Ixx heredan IEnumerable, ¿cómo se agrega a IEnumerable si un Ienumerable es de solo lectura? ... Si es demasiado complejo, no te preocupes, cuando tenga un poco de tiempo, intentaré encender el reflector. – wil

40

Escogieron el interfaz que hicieron porque ofrece una abstracción comprensible sobre las consultas mágicas que realiza Entity Framework cuando usa Linq.

Aquí está la diferencia entre las interfaces:

  • IEnumerable<T> es de sólo lectura
  • Puede añadir y eliminar elementos a un ICollection<T>
  • Puede hacerlo de acceso aleatorio (por índice) a un List<T>

Fuera de esos, ICollection y IEnumerable se correlacionan bien con las operaciones de la base de datos, ya que consultar y agregar/eliminar entidades son cosas que podrías hacer en un DB.

El acceso aleatorio por índice no se correlaciona también, ya que tendría que tener un resultado de consulta existente para iterar, o cada acceso aleatorio volvería a consultar la base de datos. Además, ¿a qué se referiría el índice? ¿Numero de fila? No hay muchas consultas de número de fila que desee hacer, y no es útil en absoluto para generar consultas más grandes. Entonces simplemente no lo admiten.

ICollection<T> es compatible, y le permitirá tanto consultar y cambiar los datos, a fin de utilizar eso.

La razón por la que List<T> funciona es porque la implementación de EF termina devolviendo una al final. Pero eso está al final de su cadena de consultas, no al principio. Entonces, hacer que sus propiedades ICollection<T> hagan más obvio que el EF crea un montón de SQL y solo devuelve un List<T> al final, en lugar de hacer consultas para cada nivel de Linq que use.

8

ICollection difiere de IEnumerable en que realmente puede agregar elementos a la colección, mientras que con IEnumerable no puede. Entonces, en sus clases de POCO, por ejemplo, desea usar ICollection si tiene la intención de permitir que se agregue la colección. Haga que ICollection sea virtual para beneficiarse de la carga diferida también.

+1

Quiero entender: puede hacer las mismas operaciones (¡y más!) Con la lista . ¿Por qué ICollection ? ¿Por qué no Lista ? Parece más simple y más poderoso. – monstro

+0

Lista Implementa ICollection e IEnumerable.Más operación pero con eso viene más sobrecarga. –

2

Aunque la pregunta se ha publicado años atrás, sigue siendo válida cuando alguien está buscando el mismo escenario.

Hay un artículo reciente [2015] CodeProject que explica la diferencia en gran detalle y representación gráfica con código de ejemplo. No se centra directamente en EF, pero todavía espero que sea de mayor ayuda:

List vs IEnumerable vs IQueryable vs ICollection vs IDictionary

Cuestiones relacionadas