.ToLookup<TSource, TKey>
devuelve un ILookup<TKey, TSource>
. ILookup<TKey, TSource>
también implementa interfaz IEnumerable<IGrouping<TKey, TSource>>
.
.GroupBy<TSource, TKey>
devuelve un IEnumerable<IGrouping<Tkey, TSource>>
.
ILookup tiene la práctica propiedad de indexador, por lo que se puede usar como en un diccionario (o en una búsqueda), mientras que GroupBy no. GroupBy sin el indexador es una molestia para trabajar; Prácticamente, la única forma en que puede hacer referencia al objeto de retorno es recorriéndolo (o utilizando otro método de extensión LINQ). En otras palabras, en cualquier caso en que funcione GroupBy, ToLookup también funcionará.
Todo esto me deja con la pregunta de por qué me molestaría en usar GroupBy. ¿Por qué debería existir?
GroupBy
EsIQuerable
,ILookup
no esLookup
, pero loGroupBy
crean cuando el resultado se enumera reference.microsoft.com/#System.Core/System/Linq/…Respuestas:
¿Qué sucede cuando llama a ToLookup en un objeto que representa una tabla de base de datos remota con mil millones de filas?
Los 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 en un objeto de este tipo?
Se crea un objeto de consulta; fin de la historia.
Cuando se enumera ese objeto de consulta, el análisis de la tabla se realiza en el servidor de la base de datos y los resultados agrupados se envían de vuelta a pedido, 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 que quiero un caché de todo ahora organizado por grupo . Llamar a GroupBy significa "Estoy construyendo un objeto para representar la pregunta '¿Cómo se verían estas cosas si las organizara por grupo?'"
fuente
IQueryable<T>
representación. Su respuesta cubre esa situación, pero cuando es simpleIEnumerable<T>
(LINQ-to-Objects) puede parecer que no hay una razón para usar uno sobre el otro, que es a lo que creo que @Shlomo está tratando de llegar. No es elIQueryable<T>
caso, sino el caso de LINQ-to-Objects.En palabras simples del mundo LINQ:
ToLookup()
- ejecución inmediataGroupBy()
- ejecución diferidafuente
Los dos son similares, pero se utilizan en diferentes escenarios.
.ToLookup()
devuelve un objeto listo para usar que ya tiene todos los grupos (pero no el contenido del grupo) cargados con entusiasmo. Por otro lado,.GroupBy()
devuelve una secuencia de grupos con carga diferida.Los diferentes proveedores de LINQ pueden tener diferentes comportamientos para la carga impaciente y perezosa de los grupos. Con LINQ-to-Object probablemente hace poca diferencia, 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 es posible que desee para hacer un filtrado adicional en la clave de grupo (que genera una
HAVING
cláusula) y luego solo obtener algunos de los grupos en lugar de todos..ToLookup()
no permitiría tal semántica ya que todos los elementos están ansiosamente agrupados.fuente