Semua contoh sejauh ini bekerja atas koleksi di memori. Mode kerja itulah LINQ to Objects: provider LINQ yang mengeksekusi operator atas IEnumerable<T> di memori proses. Karena sumbernya cukup mengimplementasikan satu interface, hampir semua tipe koleksi .NET langsung dapat dikueri.

Satu Sintaks untuk Banyak Tipe Koleksi #

Contoh berikut mengkueri string hasil pemecahan, dictionary, dan hash set dalam satu program:

csharp
string kalimat = "LINQ menyatukan kueri data dalam C#";
Dictionary<string, int> stok = new()
{
    ["Kopi Gayo"] = 40,
    ["Teh Melati"] = 60,
    ["Susu UHT"] = 35
};
HashSet<int> ganjil = new() { 1, 3, 5 };

var kataPanjang = kalimat.Split(' ').Where(k => k.Length > 4);
var hampirHabis = stok.Where(kv => kv.Value < 50).Select(kv => kv.Key);
var lebihDariDua = ganjil.Where(n => n > 2).OrderBy(n => n);

Console.WriteLine($"Kata panjang: {string.Join(", ", kataPanjang)}");
Console.WriteLine($"Stok < 50: {string.Join(", ", hampirHabis)}");
Console.WriteLine($"Ganjil > 2: {string.Join(" ", lebihDariDua)}");

Output yang Dihasilkan:

text
Kata panjang: menyatukan, kueri, dalam
Stok < 50: Kopi Gayo, Susu UHT
Ganjil > 2: 3 5

Mari kita bedah baris demi baris:

  1. kalimat.Split(' '): menghasilkan string[]; array juga mengimplementasikan IEnumerable<T>, sehingga Where langsung bekerja.
  2. stok.Where(...): Dictionary<string, int> diiterasi sebagai pasangan KeyValuePair<string, int>, sehingga syarat dapat membaca kv.Value.
  3. .Select(kv => kv.Key): projection mengubah pasangan kunci-nilai menjadi nama produk.
  4. ganjil.Where(...).OrderBy(...): HashSet<int> juga sumber LINQ yang sah; OrderBy ditambahkan agar urutan hasil deterministik.

Cakupan Sumber Data #

Sumber yang lazim untuk LINQ to Objects antara lain:

  • List<T> dan T[] untuk data berurutan
  • Dictionary<TKey,TValue> untuk pasangan kunci-nilai
  • HashSet<T> untuk himpunan unik
  • string setelah Split, atau IEnumerable<char> lewat method seperti Cast<char>

Koleksi buatan sendiri pun sah dipakai bila mengimplementasikan IEnumerable<T>, sehingga tipe domain seperti daftar produk kustom dapat langsung dikueri tanpa konversi terlebih dahulu. Syaratnya hanya satu: tipe tersebut menyediakan enumerator yang dapat ditarik elemennya satu per satu.

Pembeda LINQ to Objects dari provider lain ada pada letak eksekusi: seluruh perhitungan terjadi di memori proses yang sama, tanpa penerjemahan ke bahasa kueri luar. Eksekusi tetap bersifat malas: baris kataPanjang di atas belum menghitung apa pun sebelum string.Join mengiterasinya, sehingga sumber yang sama dapat dikueri berulang kali dengan kondisi terkini.

Karena tidak ada translasi maupun jaringan yang terlibat, LINQ to Objects menjadi tempat terbaik untuk melatih operator: sintaks yang sama persis dipakai provider lain, termasuk EF Core yang dibahas pada bab berikutnya.