.ToLookup<TSource, TKey>
retorna um ILookup<TKey, TSource>
. ILookup<TKey, TSource>
também implementa interface IEnumerable<IGrouping<TKey, TSource>>
.
.GroupBy<TSource, TKey>
retorna um IEnumerable<IGrouping<Tkey, TSource>>
.
ILookup tem a propriedade indexer útil, portanto, pode ser usado de maneira semelhante a um dicionário (ou semelhante a uma consulta), enquanto o GroupBy não pode. O GroupBy sem o indexador é difícil de trabalhar; praticamente a única maneira de fazer referência ao objeto de retorno é fazendo um loop por ele (ou usando outro método de extensão LINQ). Em outras palavras, em qualquer caso em que GroupBy funcione, ToLookup funcionará também.
Tudo isso me deixa com a pergunta: por que eu deveria me preocupar com o GroupBy? Por que deveria existir?
GroupBy
ÉIQuerable
,ILookup
não éLookup
, mas oGroupBy
cria quando o resultado é enumerado referenceource.microsoft.com/#System.Core/System/Linq/…Respostas:
O que acontece quando você chama ToLookup em um objeto que representa uma tabela de banco de dados remoto com um bilhão de linhas?
O bilhão de linhas é enviado pela rede e você constrói a tabela de pesquisa localmente.
O que acontece quando você chama GroupBy em um objeto assim?
Um objeto de consulta é construído; fim da história.
Quando esse objeto de consulta é enumerado, a análise da tabela é feita no servidor de banco de dados e os resultados agrupados são enviados de volta sob demanda, alguns de cada vez.
Logicamente, eles são a mesma coisa, mas as implicações de desempenho de cada um são completamente diferentes. Chamar ToLookup significa que quero um cache de tudo agora organizado por grupo . Chamar GroupBy significa "Estou construindo um objeto para representar a pergunta 'como seriam essas coisas se eu as organizasse em grupos?'"
fonte
IQueryable<T>
representação. Sua resposta cobre essa situação, mas quando é simplesIEnumerable<T>
(LINQ-to-Objects) pode parecer que não há motivo para usar um em vez do outro, que é o que acredito que @Shlomo está tentando chegar. Não é oIQueryable<T>
caso, mas o caso LINQ-to-Objects.Em palavras simples do mundo LINQ:
ToLookup()
- execução imediataGroupBy()
- execução adiadafonte
Os dois são semelhantes, mas são usados em cenários diferentes.
.ToLookup()
retorna um objeto pronto para usar que já possui todos os grupos (mas não o conteúdo do grupo) carregados avidamente. Por outro lado,.GroupBy()
retorna uma sequência de grupos carregada lentamente.Diferentes provedores de LINQ podem ter comportamentos diferentes para o carregamento rápido e lento dos grupos. Com LINQ-to-Object provavelmente faz pouca diferença, mas com LINQ-to-SQL (ou LINQ-to-EF, etc.), a operação de agrupamento é realizada no servidor de banco de dados em vez do cliente e, portanto, você pode desejar para fazer uma filtragem adicional na chave do grupo (o que gera uma
HAVING
cláusula) e então obter apenas alguns dos grupos em vez de todos eles..ToLookup()
não permitiria tal semântica, uma vez que todos os itens são agrupados avidamente.fonte