LINQ untuk live coding
Ringkasan satu halaman. Dari Lesson 0025. Konsep deferred/IQueryable: async/Task dan LINQ.
TS → LINQ [1]
| TypeScript | LINQ | TypeScript | LINQ |
|---|---|---|---|
filter | Where | find | FirstOrDefault |
map | Select | some / every | Any / All (kosong → true) |
flatMap | SelectMany | includes | Contains |
sort (2 kunci) | OrderBy + ThenBy(Descending) | reduce (total) | Count, Sum, Average, Max, Min |
slice | Skip(s).Take(n) | lodash maxBy/uniqBy | MaxBy, MinBy, DistinctBy (.NET 6+) |
lodash groupBy | GroupBy → IGrouping + .Key | lodash keyBy | ToDictionary(k => …, v => …) |
Method syntax untuk live coding. Query syntax (from p in … where … select p) = method syntax yang sama setelah dikompilasi [2].
Satu elemen [3]
| 0 cocok | >1 cocok | Pakai untuk | |
|---|---|---|---|
First | exception | yang pertama | pasti ada; satu dari banyak (+ OrderBy) |
FirstOrDefault | default (null / 0) | yang pertama | boleh kosong (= find) |
Single | exception | exception | harus tepat satu |
SingleOrDefault | default | exception | primary key / kolom unik → cek null → 404 |
Keempatnya mengeksekusi langsung. Exception = InvalidOperationException. EF Core: …Async.
Pola yang sering diminta
// top-N per grup (= ROW_NUMBER() OVER (PARTITION BY …))
products.GroupBy(p => p.CategoryId)
.Select(g => new { g.Key, Top = g.OrderByDescending(p => p.Price).Take(3).ToList() });
// agregat per grup (= GROUP BY)
products.GroupBy(p => p.CategoryId).Select(g => new { g.Key, Total = g.Sum(p => p.Price * p.Stock) });
// duplikat (= GROUP BY … HAVING COUNT(*) > 1)
products.GroupBy(p => p.Name).Where(g => g.Count() > 1).Select(g => g.Key);
// gabung (= INNER JOIN; sisi tanpa pasangan hilang)
products.Join(categories, p => p.CategoryId, c => c.Id, (p, c) => new { p.Name, Cat = c.Name });
// termasuk grup kosong: mulai dari sisi "induk"
categories.Select(c => new { c.Name, Total = products.Where(p => p.CategoryId == c.Id).Sum(p => p.Stock) });
// "tidak punya satu pun yang …"
categories.Where(c => !products.Any(p => p.CategoryId == c.Id && p.Stock == 0));
Jebakan
- Urutan di dalam grup:
OrderByDescendingdulu, baruTake.MaxBymengembalikan satu elemen. - EF Core: method C# biasa hanya boleh di
Selectterakhir (top-level projection). DiWhere/OrderBy/GroupBy→ runtime exception, bukan compile error [4]. - GroupBy di EF Core: + agregat →
GROUP BY/HAVING[5]; top-N per grup →ROW_NUMBERsejak EF Core 6 [6]. - Multiple enumeration: hasil tidak di-cache;
Count()+foreachpada query = dua query. Materialisasi sekali (ToListAsync) lalu pakai list-nya [7].
Jawaban 60 detik: First vs Single
First mengambil yang pertama cocok dan melempar exception kalau tidak ada; FirstOrDefault mengembalikan default (null untuk reference type), padanan find.
Single menegaskan tepat satu: exception kalau nol atau lebih dari satu; SingleOrDefault default kalau nol, tetap exception kalau lebih dari satu.
Primary key → SingleOrDefault + cek null untuk 404; satu dari banyak → OrderBy + FirstOrDefault. Semuanya eksekusi langsung; di EF Core pakai versi async.
Sumber: [1] Standard query operators overview · [2] Write LINQ queries · [3] Enumerable.Single (lihat juga First/FirstOrDefault/SingleOrDefault) · [4] EF Core: Client vs. Server Evaluation · [5] EF Core: Complex Query Operators · [6] What's new in EF Core 6 · [7] CA1851