ToLookup ve GroupBy neden farklı?


111

.ToLookup<TSource, TKey>döndürür bir ILookup<TKey, TSource>. ILookup<TKey, TSource>ayrıca arayüz uygular IEnumerable<IGrouping<TKey, TSource>>.

.GroupBy<TSource, TKey>döndürür bir IEnumerable<IGrouping<Tkey, TSource>>.

ILookup, kullanışlı dizin oluşturucu özelliğine sahiptir, bu nedenle sözlüğe benzer (veya arama benzeri) bir şekilde kullanılabilir, oysa GroupBy bunu yapamaz. Indexer olmadan GroupBy, çalışmak için bir sıkıntıdır; Daha sonra dönüş nesnesine başvurmanın hemen hemen tek yolu, onu döngü yapmaktır (veya başka bir LINQ-extension yöntemi kullanmaktır). Başka bir deyişle, GroupBy'nin çalıştığı her durumda, ToLookup da çalışacaktır.

Tüm bunlar beni neden GroupBy ile uğraşayım? Neden var olmalı?


7
GroupByIQuerable, ILookupdeğil
Magnus

5
GroupBy listeyi numaralandırmaz ToLookup, onu ToList / ToArray
Aducci

3
Yinelemesi olduğu iddia edilen soru ToLookup yerine GroupBy ve ILookup yerine IGrouping ile ilgili olduğu için bunu yeniden açılmak üzere aday gösterdim . Bunlar arasındaki farklar, bunlar arasındaki farklardan farklıdır. Bu, sorular arasındaki cevaplardaki farklılıklardan anlaşılmalıdır.
Sam

1
her ikisi de bir oluşturur Lookup, ancak GroupBysonuç numaralandırıldığında bunu oluşturur. reference.microsoft.com/#System.Core/System/Linq/…
Slai

Yanıtlar:


175

GroupBy ile neden uğraşayım ki? Neden var olmalı?

İçinde milyar satır bulunan uzak veritabanı tablosunu temsil eden bir nesnede ToLookup'ı çağırdığınızda ne olur?

Milyarlarca satır kablo üzerinden gönderilir ve arama tablosunu yerel olarak oluşturursunuz.

Böyle bir nesne için GroupBy'yi aradığınızda ne olur?

Bir sorgu nesnesi oluşturulur; Hikayenin sonu.

Bu sorgu nesnesi numaralandırıldığında, tablonun analizi veritabanı sunucusunda yapılır ve gruplanan sonuçlar bir seferde birkaç istek üzerine geri gönderilir .

Mantıksal olarak aynı şeylerdir ancak her birinin performans sonuçları tamamen farklıdır. ToLookup'ı aramak , şu anda gruba göre organize edilmiş her şeyin bir önbelleğini istediğim anlamına geliyor . GroupBy'nin çağrılması, "'Bunları gruba göre düzenlersem bu şeyler nasıl görünürdü?' Sorusunu temsil edecek bir nesne oluşturuyorum anlamına gelir."


6
Poster özellikle bir IQueryable<T>temsili hedef almıyor . Cevabınız bu durumu kapsıyor, ancak söz konusu olduğunda IEnumerable<T>(LINQ-to-Objects), birini diğerinin üzerine kullanmak için bir neden yokmuş gibi görünebilir, ben de @Shlomo'nun ulaşmaya çalıştığına inanıyorum. DeğilIQueryable<T> öyledir, ancak LINQ Nesneler durumda.
casperOne

21
@casperOne: Söylediğimi anlayamadığınızı düşünüyorum. Hatta LINQ-itiraz durumunda, çağıran GroupBy hala topluluğu üzerinde yineleme etmez. (Aducci'nin sildiğiniz cevapta işaret ettiği gibi) Bu temel bir fark.
Eric Lippert

12
@EricLippert: Ancak bu, uygulamanın yalnızca bir yan etkisi mi yoksa uygulamada hangi değişiklikler yapılırsa yapılsın, ToLookup'ı aradığınızda numaralandırılmasının yineleneceği garanti ediliyor mu?

9
@Will: Mükemmel bir noktaya değindin; belgeler ToLookup'ın "istekli" olduğunu garanti etmez. Muhtemelen bunu not etmelidir.
Eric Lippert

10
Heves bunu açıklıyor. "ToMetaType" ın dili bence şevk anlamına geliyor; açıkçası uygulamaya bırakılmıştır. Diğer 'Kime'ların hepsi heveslidir (ToList, ToArray, ToDictionary). Teşekkürler beyler.
Shlomo

98

Basit LINQ dünyası sözleriyle:

  • ToLookup() - acil infaz
  • GroupBy() - ertelenmiş yürütme

17

İkisi benzerdir, ancak farklı senaryolarda kullanılır. .ToLookup()tüm grupların (ancak grubun içeriğinin değil) hevesle yüklenmiş olduğu, kullanıma hazır bir nesne döndürür. Öte yandan, .GroupBy()tembel yüklü bir grup dizisi döndürür.

Farklı LINQ sağlayıcıları, grupların istekli ve tembel olarak yüklenmesi için farklı davranışlara sahip olabilir. LINQ-to-Object ile muhtemelen çok az fark yaratır, ancak LINQ-to-SQL (veya LINQ-to-EF, vb.) İle gruplama işlemi, istemci yerine veritabanı sunucusunda gerçekleştirilir ve bu nedenle, Grup anahtarında ek bir filtreleme yapmak için (ki bu bir HAVINGyan tümce oluşturur ) ve sonra hepsi yerine grupların yalnızca bir kısmını elde edin. .ToLookup()tüm öğeler hevesle gruplandığından bu tür anlambilimlere izin verilmez.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.