2012-04-18 25 views
75

.ToLookup<TSource, TKey> devuelve ILookup<TKey, TSource>. ILookup<TKey, TSource> también implementa la interfaz IEnumerable<IGrouping<TKey, TSource>>.¿Por qué ToLookup y GroupBy son diferentes?

.GroupBy<TSource, TKey> devuelve IEnumerable<IGrouping<Tkey, TSource>>.

ILookup tiene la propiedad de indexador útil, por lo que se puede utilizar en forma de diccionario (o de búsqueda), mientras que GroupBy no puede. GroupBy sin el indexador es un dolor para trabajar; más o menos la única manera en que puede hacer referencia al objeto de retorno es recorriéndolo (o usando otro método de extensión LINQ). En otras palabras, cualquier caso en que GroupBy funcione, ToLookup también funcionará.

Todo esto me deja con la pregunta ¿por qué alguna vez me molestaría con GroupBy? ¿Por qué debería existir?

+5

'GroupBy' es' IQuerable', 'ILookup' no es – Magnus

+5

GroupBy doesn' t enumerar la lista [ToLookup] (http://msdn.microsoft.com/en-us/library/system.linq.enumerable.tolookup.aspx) lo enumera de la misma manera ToList/ToArray – Aducci

+3

Lo nominé para la reapertura ya que la pregunta es supuestamente una el duplicado de es aproximadamente * IGrouping * en lugar de * GroupBy * y * ILookup * en lugar de * ToLookup *. Las diferencias entre ellos son diferentes a las diferencias entre estos. Esto debería ser evidente a partir de las diferencias en las respuestas entre las preguntas. – Sam

Respuesta

130

¿Por qué me molestaría alguna vez con GroupBy? ¿Por qué debería existir?

¿Qué sucede cuando llama a ToLookup en un objeto que representa una tabla de base de datos remota con mil millones de filas en él?

Las mil millones de filas se envían a través del cable y usted crea la tabla de búsqueda localmente.

¿Qué sucede cuando llamas a GroupBy sobre tal objeto?

Se genera un objeto de consulta; fin de la historia.

Cuando ese objeto de consulta se enumeran a continuación, el análisis de la tabla se hace en el servidor de base de datos y los resultados agrupados son enviados de vuelta a la carta unos pocos a la vez.

Lógicamente son lo mismo, pero las implicaciones de rendimiento de cada uno son completamente diferentes. Llamar a ToLookup significa Quiero un caché de todo el asunto ahora organizado por el grupo. Llamar a GroupBy significa "Estoy construyendo un objeto para representar la pregunta '¿Qué aspecto tendrían estas cosas si las organizara por grupo?'"

+3

El póster doesn ' t específicamente dirigido a una representación 'IQueryable '. Su respuesta cubre esa situación, pero cuando es simplemente ol 'IEnumerable ' (LINQ-to-Objects) puede parecer que no hay una razón para usar una sobre la otra, que es lo que creo que @Shlomo está intentando llegar a. * No * el caso 'IQueryable ', pero el caso LINQ-to-Objects. – casperOne

+0

Me parece beneficioso para LINQ ser consistente, siempre que sea posible. Creo que demostrar su utilidad en LINQ-to-SQL es suficiente para justificar dejarlo en LINQ-to-Objects. – Brian

+19

@casperOne: Creo que no has entendido mi punto. Incluso en el caso LINQ-to-objects, la llamada a GroupBy * still * no itera sobre la colección. (Como señaló Aducci en la respuesta que eliminaste). Esa es una diferencia fundamental. –

12

Las dos son similares, pero se usan en diferentes escenarios. .ToLookup() devuelve un objeto listo para usar que ya tiene todos los grupos (pero no el contenido del grupo) cargados ansiosamente. Por otro lado, .GroupBy() devuelve una secuencia de grupos con carga diferida.

Diferentes proveedores de LINQ pueden tener diferentes comportamientos para la carga ansiosa y diferida de los grupos. Con LINQ-to-Object probablemente tenga poca importancia, pero con LINQ-to-SQL (o LINQ-to-EF, etc.), la operación de agrupación se realiza en el servidor de la base de datos en lugar del cliente, por lo que puede querer para hacer un filtrado adicional en la clave del grupo (que genera una cláusula HAVING) y luego solo obtener algunos de los grupos en lugar de todos. .ToLookup() no permitiría tal semántica, ya que todos los artículos están agrupados con entusiasmo.

70

En palabras sencillas LINQ-mundo:

  • ToLookup() - ejecución inmediata
  • GroupBy() - ejecución diferida
Cuestiones relacionadas