Sintaks metode LINQ (Language Integrated Query) membentuk query dengan memanggil metode ekstensi pada Enumerable secara berantai, dan setiap metode menerima lambda, yaitu fungsi ringkas yang ditulis tanpa nama. Topik ini membahas empat operator yang paling sering digunakan, yaitu Where untuk menyaring, Select untuk mengubah bentuk, OrderBy untuk mengurutkan, serta pasangan First dan FirstOrDefault untuk mengambil satu elemen. Setiap operator disertai contoh yang dijalankan dan keluaran aslinya.
Where untuk menyaring#
Metode Where menerima lambda yang disebut predicate, yaitu fungsi yang mengembalikan true atau false untuk setiap elemen, kemudian menghasilkan barisan yang hanya memuat elemen dengan predikat true. Sumbernya tidak berubah, karena Where mengembalikan barisan baru yang menelusuri sumbernya pada saat penelusuran dilakukan.
// Contoh: Where menyaring nilai ujian yang memenuhi ambang lulus
List<int> nilaiUjian = new() { 84, 60, 90, 55, 75 };
IEnumerable<int> lulus = nilaiUjian.Where(n => n >= 75);
Console.WriteLine(string.Join(", ", lulus));84, 90, 75Lambda n => n >= 75 dibaca sebagai fungsi yang menerima n lalu mengembalikan hasil n >= 75. Barisan lulus memuat tiga nilai karena 60 dan 55 tidak memenuhi ambang tersebut. Beberapa pemanggilan Where dapat dirangkai, dan hasilnya setara dengan satu predikat yang menggabungkan semua syarat dengan operator logika.
Operator lain dalam keluarga yang sama sering berdampingan dengan Where. Metode Count() menghitung banyaknya elemen yang lolos, Any() memeriksa apakah ada satu elemen pun yang lolos, sedangkan Take(n) dan Skip(n) memotong barisan dari depan. Seluruhnya bekerja pada barisan yang sama tanpa perulangan manual, sehingga penyaringan dan pengambilan sebagian data dapat dirancang dalam satu alur.
Select untuk mengubah bentuk#
Metode Select menerima lambda yang menentukan bentuk baru setiap elemen, sehingga barisan hasilnya berisi nilai turunan dan bukan salinan sumbernya. Proses ini disebut proyeksi, yaitu pemetaan setiap elemen sumber menjadi satu nilai atau objek baru. Contoh berikut memetakan nilai ujian menjadi label kategorinya.
// Contoh: Select mengubah setiap nilai menjadi label kategori
string Kategori(int nilai)
{
return nilai >= 75 ? "lulus" : "remedial";
}
List<int> nilaiUjian = new() { 84, 60, 90 };
foreach (string label in nilaiUjian.Select(n => Kategori(n)))
{
Console.WriteLine(label);
}lulus
remedial
lulusJumlah elemen barisan hasil Select selalu sama dengan sumbernya, sedangkan tipenya mengikuti nilai kembalian lambda tersebut. Lambda pada Select juga boleh menghasilkan objek baru, misalnya new { Nama = p.Nama, Status = Kategori(p.Nilai) }, dan bentuk objek tanpa nama seperti itu disebut anonymous type.
Proyeksi bertingkat juga dimungkinkan, misalnya Select yang hasilnya lalu disaring lagi dengan Where pada rantai yang sama. Urutan operator menentukan maknanya, karena menyaring setelah memproyeksikan berarti menilai bentuk barunya, sedangkan menyaring lebih dahulu menilai elemen aslinya. Kaidah praktisnya adalah menyaring terlebih dahulu untuk memperkecil data, kemudian memproyeksikan bentuk akhirnya.
OrderBy untuk mengurutkan#
Metode OrderBy menghasilkan barisan yang elemennya tertata menaik menurut kunci yang dipilih lambda, sedangkan OrderByDescending menghasilkan urutan menurun. Kunci pengurutan boleh berupa bagian data, misalnya nilai, nama, atau tanggal. Metode ThenBy melengkapi urutan utama dengan kunci kedua untuk elemen yang kunci utamanya sama.
// Contoh: OrderBy dan OrderByDescending menata ulang urutan nilai
List<int> nilaiUjian = new() { 84, 60, 90, 75 };
Console.WriteLine($"Menaik: {string.Join(", ", nilaiUjian.OrderBy(n => n))}");
Console.WriteLine($"Menurun: {string.Join(", ", nilaiUjian.OrderByDescending(n => n))}");Menaik: 60, 75, 84, 90
Menurun: 90, 84, 75, 60Contoh berikut mengurutkan daftar peserta berdasarkan nilai, lalu nama sebagai kunci kedua. Dua peserta dengan nilai 84 akhirnya tampil menurut abjad nama karena peran ThenBy.
Metode OrderBy tidak mengubah collection sumbernya, tetapi menghasilkan barisan baru yang urutannya tertata, sehingga data asli tetap utuh untuk pengolahan lain. Kunci pengurutan boleh berupa hasil perhitungan lambda, misalnya panjang string atau selisih dari nilai acuan, selama tipenya mendukung perbandingan.
// Contoh: ThenBy mengurutkan nama untuk nilai yang sama
List<Peserta> peserta = new()
{
new Peserta("Budi", 84),
new Peserta("Ali", 84),
new Peserta("Citra", 90)
};
foreach (Peserta p in peserta.OrderBy(p => p.Nilai).ThenBy(p => p.Nama))
{
Console.WriteLine($"{p.Nama}: {p.Nilai}");
}
record Peserta(string Nama, int Nilai);Ali: 84
Budi: 84
Citra: 90First dan FirstOrDefault#
Metode First mengembalikan elemen pertama yang cocok dengan predikatnya, sedangkan FirstOrDefault mengembalikan nilai bawaan tipe ketika tidak ada yang cocok. Nilai bawaan untuk tipe angka adalah 0, untuk string adalah null pada konteks nullable yang dinonaktifkan, dan untuk tipe referensi lain adalah null. Perbedaan ini menentukan pilihan, karena First menganggap ketiadaan hasil sebagai kondisi yang tidak wajar.
// Contoh: First melempar exception dan FirstOrDefault mengembalikan nilai bawaan
List<int> nilaiUjian = new() { 84, 60, 90 };
int tertinggi = nilaiUjian.First(n => n >= 80);
Console.WriteLine($"Nilai pertama minimal 80: {tertinggi}");
int tidakAda = nilaiUjian.FirstOrDefault(n => n >= 95);
Console.WriteLine($"Nilai pertama minimal 95: {tidakAda}");
try
{
int gagal = nilaiUjian.First(n => n >= 95);
Console.WriteLine($"Nilai pertama minimal 95: {gagal}");
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex.Message);
}Nilai pertama minimal 80: 84
Nilai pertama minimal 95: 0
Sequence contains no matching elementPemanggilan First dengan predikat yang tidak dipenuhi elemen mana pun melempar exception InvalidOperationException dengan pesan Sequence contains no matching element. Ketiadaan hasil pada FirstOrDefault tidak berbahaya, tetapi nilai 0 pada contoh di atas bisa juga berarti sebuah nilai ujian yang sah, sehingga kerancuan itu perlu dipastikan sebelum metode ini dipilih. Pasangan serupa juga tersedia, yaitu Single dan SingleOrDefault yang mengharuskan hasilnya paling banyak satu.
Tanpa predikat, First mengembalikan elemen paling depan apa adanya, sedangkan Last dan LastOrDefault mengambil dari ujung sebaliknya. Pada barisan hasil OrderBy, elemen pertama hasil First pasti memuat kunci terkecil, sehingga kombinasi keduanya sering menggantikan perulangan pencarian manual.
Contoh program utuh#
Program berikut merangkum keempat operator pada satu daftar peserta ujian.
// Program contoh Where, Select, OrderBy, serta First dan FirstOrDefault
// Data nilai ujian lima peserta
List<Peserta> peserta = new()
{
new Peserta("Budi", 84),
new Peserta("Ali", 60),
new Peserta("Citra", 90),
new Peserta("Dewi", 55),
new Peserta("Eka", 75)
};
// Where: menyaring nilai yang memenuhi ambang lulus
IEnumerable<int> semuaNilai = peserta.Select(p => p.Nilai);
Console.WriteLine($"Nilai yang lulus: {string.Join(", ", semuaNilai.Where(n => n >= 75))}");
// Select: mengubah setiap peserta menjadi baris laporan
foreach (string baris in peserta.Select(p => $"{p.Nama} dinyatakan {Kategori(p.Nilai)}"))
{
Console.WriteLine(baris);
}
// OrderBy dan ThenBy: nilai menaik, lalu nama menaik untuk nilai yang sama
Console.WriteLine("Urutan berdasarkan nilai lalu nama:");
foreach (Peserta p in peserta.OrderBy(p => p.Nilai).ThenBy(p => p.Nama))
{
Console.WriteLine($"{p.Nama}: {p.Nilai}");
}
// First: elemen pertama yang cocok, FirstOrDefault: nilai bawaan bila tidak ada
Console.WriteLine($"First minimal 80: {semuaNilai.First(n => n >= 80)}");
Console.WriteLine($"FirstOrDefault minimal 95: {semuaNilai.FirstOrDefault(n => n >= 95)}");
try
{
Console.WriteLine($"First minimal 95: {semuaNilai.First(n => n >= 95)}");
}
catch (InvalidOperationException ex)
{
Console.WriteLine(ex.Message);
}
string Kategori(int nilai)
{
return nilai >= 75 ? "lulus" : "remedial";
}
record Peserta(string Nama, int Nilai);Nilai yang lulus: 84, 90, 75
Budi dinyatakan lulus
Ali dinyatakan remedial
Citra dinyatakan lulus
Dewi dinyatakan remedial
Eka dinyatakan lulus
Urutan berdasarkan nilai lalu nama:
Dewi: 55
Ali: 60
Eka: 75
Budi: 84
Citra: 90
First minimal 80: 84
FirstOrDefault minimal 95: 0
Sequence contains no matching elementJalankan program tersebut dari folder topik dengan perintah berikut.
# aktifkan .NET yang terpasang di sandbox
export DOTNET_ROOT=/home/kal/.dotnet PATH=/home/kal/.dotnet:$PATH DOTNET_CLI_TELEMETRY_OPTOUT=1 DOTNET_NOLOGO=1
# jalankan program contoh dari folder topik
dotnet run --file Program.csNilai yang lulus: 84, 90, 75
Budi dinyatakan lulus
Ali dinyatakan remedial
Citra dinyatakan lulus
Dewi dinyatakan remedial
Eka dinyatakan lulus
Urutan berdasarkan nilai lalu nama:
Dewi: 55
Ali: 60
Eka: 75
Budi: 84
Citra: 90
First minimal 80: 84
FirstOrDefault minimal 95: 0
Sequence contains no matching elementKesalahan umum#
- Memanggil
Firstpada query yang hasilnya mungkin kosong tanpa rencana penanganan. ExceptionInvalidOperationExceptionterjadi pada runtime, dan perbaikannya adalah menggunakanFirstOrDefaultdisertai pemeriksaan nilai bawaan. - Menganggap 0 dari
FirstOrDefaultsebagai bukti ketiadaan hasil pada tipe angka. Nilai 0 dapat berupa data yang sah, sehingga pemeriksaan keberadaan hasil terlebih dahulu, misalnya denganAny(), memberikan kepastian yang lebih baik. - Mengurutkan dengan
OrderBydua kali secara berantai. Pemanggilan kedua mengganti urutan pertama, sedangkan kunci tambahan yang dimaksud seharusnya ditulis denganThenBy.
Ringkasan#
Wheremenyaring elemen dengan predikat lambda, dan sumbernya tidak pernah berubah.Selectmemetakan setiap elemen menjadi bentuk baru dengan jumlah yang tetap sama.OrderBydanOrderByDescendingmenata urutan menurut kunci, sedangkanThenBymenambahkan kunci kedua untuk nilai yang seri.Firstmelempar exception ketika tidak ada hasil, sedangkanFirstOrDefaultmengembalikan nilai bawaan tipe dan menuntut kehati-hatian terhadap kerancuan nilai itu.
Referensi#
- LINQ overview — Microsoft Learn — Gambaran LINQ pada C# beserta kaitan sintaks metode dan query.
- Filtering data — Microsoft Learn
— Dokumentasi operator penyaringan, termasuk perilaku
Where. - Enumerable.Where — Microsoft Learn
— Rujukan API lengkap metode
Wherebeserta overload-nya. - Lambda expressions — Microsoft Learn — Rujukan sintaks lambda yang menjadi argumen operator LINQ.