2012-04-18 9 views
75

.ToLookup<TSource, TKey> restituisce un ILookup<TKey, TSource>. ILookup<TKey, TSource> implementa anche l'interfaccia IEnumerable<IGrouping<TKey, TSource>>.Perché ToLookup e GroupBy sono diversi?

.GroupBy<TSource, TKey> restituisce un IEnumerable<IGrouping<Tkey, TSource>>.

iLookup ha la proprietà indicizzatore a portata di mano, in modo che possa essere utilizzato in modo simile ai dizionari (o lookup-like), mentre GroupBy non può. GroupBy senza l'indicizzatore è un problema con cui lavorare; praticamente l'unico modo in cui puoi quindi fare riferimento all'oggetto restituito è eseguirne il looping (o usare un altro metodo di estensione LINQ). In altre parole, in ogni caso che funziona GroupBy, funzionerà anche ToLookup.

Tutto questo mi lascia con la domanda perché mai dovrei perdere tempo con GroupBy? Perché dovrebbe esistere?

+5

'GroupBy' è' IQuerable', 'ILookup' non è – Magnus

+5

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

+3

L'ho nominato per la riapertura poiché la domanda è presumibilmente a duplicato di è su * IGrouping * piuttosto che su * GroupBy * e * ILookup * piuttosto che * ToLookup *. Le differenze tra queste sono diverse dalle differenze tra queste. Questo dovrebbe essere evidente dalle differenze nelle risposte tra le domande. – Sam

risposta

130

perché dovrei mai preoccuparmi di GroupBy? Perché dovrebbe esistere?

Cosa succede quando si chiama ToLookup su un oggetto che rappresenta una tabella di database remoto con un miliardo di righe in esso?

Il miliardo di righe vengono inviati attraverso il filo, e si costruiscono la tabella di ricerca a livello locale.

Cosa succede quando si chiama GroupBy su un tale oggetto?

Viene creato un oggetto query; fine della storia.

Quando l'oggetto query viene enumerato quindi l'analisi della tabella è fatto sul server di database ed i risultati raggruppati vengono inviati indietro su richiesta un po 'alla volta.

Logicamente sono la stessa cosa ma le implicazioni sulle prestazioni di ciascuna sono completamente diverse. Calling ToLookup significa Voglio una cache dell'intera cosa ora organizzata dal gruppo. Chiamare GroupBy significa "Sto costruendo un oggetto per rappresentare la domanda" come sarebbero queste cose se le organizzassi per gruppo? "

+3

Il poster non fa t mirare in modo specifico ad una rappresentazione 'IQueryable '. La tua risposta copre quella situazione, ma quando è semplicemente normale 'IEnumerable ' (LINQ-to-Objects) può sembrare che non ci sia un motivo per usarne uno sull'altro, che è quello che credo @Shlomo sta provando a arrivare a. * Non * il caso 'IQueryable ', ma il caso LINQ-to-Objects. – casperOne

+0

Mi sembra utile per LINQ essere coerente, laddove possibile. Penso che dimostrare la sua utilità in LINQ-to-SQL sia sufficiente per giustificare il fatto di lasciarlo in LINQ-to-Objects. – Brian

+19

@casperOne: Penso che tu abbia omesso di comprendere il mio punto. Anche nel caso LINQ-to-objects, chiamare GroupBy * still * non itera sulla collezione. (Come ha sottolineato Aducci nella risposta che hai cancellato). Questa è una differenza fondamentale. –

12

Le due sono simili, ma vengono utilizzate in diversi scenari. .ToLookup() restituisce un oggetto pronto per l'uso che ha già tutti i gruppi (ma non il contenuto del gruppo) caricati con entusiasmo. D'altra parte, .GroupBy() restituisce una sequenza di gruppi pigri.

Diversi fornitori di LINQ possono avere comportamenti diversi per il carico ansioso e pigro dei gruppi. Con LINQ-to-Object probabilmente fa poca differenza, ma con LINQ-to-SQL (o LINQ-to-EF, ecc.), L'operazione di raggruppamento viene eseguita sul server del database anziché sul client, quindi è possibile fare un ulteriore filtraggio sulla chiave di gruppo (che genera una clausola HAVING) e quindi ottenere solo alcuni dei gruppi invece di tutti loro. .ToLookup() non consentirebbe una tale semantica poiché tutti gli elementi sono raggruppati in modo avido.

70

In parole semplici LINQ-mondo:

  • ToLookup() - esecuzione immediata
  • GroupBy() - esecuzione differita
Problemi correlati