Mengapa ToLookup dan GroupBy berbeda?


111

.ToLookup<TSource, TKey>mengembalikan sebuah ILookup<TKey, TSource>. ILookup<TKey, TSource>juga mengimplementasikan antarmuka IEnumerable<IGrouping<TKey, TSource>>.

.GroupBy<TSource, TKey>mengembalikan sebuah IEnumerable<IGrouping<Tkey, TSource>>.

ILookup memiliki properti pengindeks praktis, sehingga dapat digunakan dengan cara seperti kamus (atau mirip pencarian), sedangkan GroupBy tidak bisa. GroupBy tanpa pengindeks sulit untuk dikerjakan; cukup banyak satu-satunya cara agar Anda dapat mereferensikan objek yang dikembalikan adalah dengan mengulanginya (atau menggunakan metode ekstensi LINQ lainnya). Dengan kata lain, setiap kasus dimana GroupBy berfungsi, ToLookup juga akan berfungsi.

Semua ini membuat saya bertanya-tanya mengapa saya harus repot-repot dengan GroupBy? Kenapa harus ada?


7
GroupByApakah IQuerable, ILookuptidak
Magnus

5
GroupBy tidak menghitung daftar ToLookup dengan cara yang sama ToList / ToArray
Aducci

3
Saya telah menominasikan ini untuk membuka kembali karena pertanyaan yang diduga duplikatnya adalah tentang IGrouping daripada GroupBy dan ILookup daripada ToLookup . Perbedaan diantara keduanya berbeda dengan perbedaan diantara keduanya. Hal ini terlihat dari perbedaan jawaban antar pertanyaan.
Sam

1
keduanya membuat Lookup, tetapi GroupBymembuatnya ketika hasilnya disebutkan referenceource.microsoft.com/#System.Core/System/Linq/…
Slai

Jawaban:


175

mengapa saya harus repot-repot dengan GroupBy? Kenapa harus ada?

Apa yang terjadi jika Anda memanggil ToLookup pada objek yang mewakili tabel database jarak jauh dengan satu miliar baris di dalamnya?

Miliaran baris dikirim melalui kabel, dan Anda membangun tabel pencarian secara lokal.

Apa yang terjadi ketika Anda memanggil GroupBy pada objek seperti itu?

Objek kueri dibangun; Akhir dari cerita.

Ketika objek kueri tersebut dihitung, maka analisis tabel dilakukan pada server database dan hasil yang dikelompokkan dikirim kembali sesuai permintaan beberapa pada satu waktu.

Secara logis mereka adalah hal yang sama tetapi implikasi kinerja dari masing-masing sangat berbeda. Memanggil ToLookup berarti saya ingin semua cache sekarang ini diatur oleh grup . Memanggil GroupBy berarti "Saya sedang membangun sebuah objek untuk mewakili pertanyaan 'seperti apa hal-hal ini jika saya mengaturnya berdasarkan grup?'"


6
Poster tidak secara khusus menargetkan IQueryable<T>representasi. Jawaban Anda mencakup situasi itu, tetapi ketika itu sederhana IEnumerable<T>(LINQ-to-Objects) sepertinya tidak ada alasan untuk menggunakan salah satu dari yang lain, itulah yang saya percaya @Shlomo coba lakukan. Tidak satu IQueryable<T>kasus, tetapi kasus LINQ-to-Objek.
casperOne

21
@casperOne: Saya pikir Anda telah gagal memahami maksud saya. Bahkan dalam kasus LINQ-to-objects, memanggil GroupBy masih tidak mengulang-ulang koleksi. (Seperti yang ditunjukkan Aducci dalam jawaban yang Anda hapus.) Itu adalah perbedaan mendasar.
Eric Lippert

12
@EricLippert: Tetapi apakah itu hanya efek samping dari implementasi atau apakah itu dijamin bahwa enumerable akan diulang ketika Anda memanggil ToLookup, tidak peduli perubahan apa yang dilakukan pada implementasi?

9
@ Will: Anda membuat poin yang sangat baik; dokumentasi tidak menjamin bahwa ToLookup "bersemangat". Mungkin harus dicatat itu.
Eric Lippert

10
Semangat menjelaskannya. Bahasa 'ToMetaType' menurut saya menyiratkan keinginan; meskipun jelas tergantung pada implementasinya. 'To's lainnya sangat bersemangat (ToList, ToArray, ToDictionary). Terima kasih teman-teman.
Shlomo

98

Dengan kata-kata dunia LINQ sederhana:

  • ToLookup() - eksekusi segera
  • GroupBy() - eksekusi yang ditangguhkan

17

Keduanya serupa, tetapi digunakan dalam skenario yang berbeda. .ToLookup()mengembalikan objek siap pakai yang sudah memiliki semua grup (tetapi bukan konten grup) yang dimuat dengan penuh semangat. Di sisi lain, .GroupBy()mengembalikan urutan grup yang lambat dimuat.

Penyedia LINQ yang berbeda mungkin memiliki perilaku yang berbeda untuk pemuatan grup yang bersemangat dan lambat. Dengan LINQ-to-Object itu mungkin membuat sedikit perbedaan, tetapi dengan LINQ-to-SQL (atau LINQ-to-EF, dll.), Operasi pengelompokan dilakukan di server database daripada di klien, jadi Anda mungkin ingin untuk melakukan pemfilteran tambahan pada kunci grup (yang menghasilkan HAVINGklausa) dan kemudian hanya mendapatkan beberapa grup alih-alih semuanya. .ToLookup()tidak akan mengizinkan semantik seperti itu karena semua item dikelompokkan dengan penuh semangat.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.