Sintaks query adalah bentuk deklaratif LINQ yang menulis query dengan klausa from, where, dan select, sehingga strukturnya mirip kalimat pernyataan data dan bukan rantai pemanggilan metode. Topik ini membahas bentuk dasar query, klausa pendukung seperti orderby, let, dan from ganda, serta pertimbangan memilih antara sintaks query dan sintaks metode. Semua contoh dijalankan langsung, dan keluaran aslinya ditempel setelah setiap potongan kode.
Bentuk from, where, dan select#
Setiap query dimulai dengan klausa from yang menyatakan sumber dan variabel rentangnya, dilanjutkan where yang menyaring, dan diakhiri select yang menentukan bentuk keluaran. Variabel rentang, misalnya n, mewakili elemen sumber yang sedang dinilai pada setiap tahap. Kompilator menerjemahkan bentuk query ini menjadi pemanggilan metode Where dan Select yang persis, sehingga kedua bentuk berikut menghasilkan barisan yang sama.
// Contoh: bentuk metode dan bentuk query menghasilkan barisan yang sama
List<int> nilaiUjian = new() { 84, 60, 90, 55, 75 };
IEnumerable<int> lulusMetode = nilaiUjian.Where(n => n >= 75);
IEnumerable<int> lulusQuery =
from n in nilaiUjian
where n >= 75
select n;
Console.WriteLine($"Metode: {string.Join(", ", lulusMetode)}");
Console.WriteLine($"Query: {string.Join(", ", lulusQuery)}");Metode: 84, 90, 75
Query: 84, 90, 75Kesamaan keluaran tersebut bukan kebetulan, melainkan hasil penerjemahan kompilator. Karena keduanya berujung pada metode Enumerable yang sama, perilaku eksekusinya juga sama, termasuk sifat eksekusi tundanya. Pilihan antara kedua bentuk sepenuhnya perkara keterbacaan dan bukan perkara performa.
Variabel hasil query umumnya dideklarasikan dengan var karena tipe keluarannya kadang panjang, terutama ketika select menghasilkan objek tanpa nama. Penulisan tipe eksplisit seperti IEnumerable<int> tetap sah pada proyeksi yang sederhananya, dan pilihan keduanya tidak mengubah perilaku query. Variabel rentang hanya hidup di dalam query itu, sehingga penggunaannya tidak memengaruhi variabel lain yang namanya sama.
orderby, let, dan beberapa from#
Klausa orderby mengurutkan hasil dengan arah ascending atau descending, sedangkan select boleh berupa ekspresi yang menghasilkan bentuk baru. Susunan klausa pada contoh berikut menyaring dahulu, kemudian mengurutkan menurun, lalu memetakan setiap nilai menjadi baris laporan.
// Contoh: orderby descending dan select ekspresi dalam bentuk query
List<int> nilaiUjian = new() { 84, 60, 90, 55, 75 };
var laporan =
from n in nilaiUjian
where n >= 75
orderby n descending
select $"Nilai {n} dinyatakan lulus";
foreach (string baris in laporan)
{
Console.WriteLine(baris);
}Nilai 90 dinyatakan lulus
Nilai 84 dinyatakan lulus
Nilai 75 dinyatakan lulusKlausa let menyimpan hasil sebuah perhitungan ke variabel sementara yang dapat dirujuk pada klausa berikutnya. Kegunaannya paling terasa ketika nilai itu digunakan lebih dari satu kali, sehingga perhitungan cukup ditulis sekali.
// Contoh: klausa let menyimpan hitungan panjang kata yang digunakan berulang
string kalimat = "penghitung kata menghitung kata yang berulang";
var kataPanjang =
from kata in kalimat.Split(' ')
let panjang = kata.Length
where panjang > 5
select $"{kata} ({panjang} huruf)";
foreach (string baris in kataPanjang)
{
Console.WriteLine(baris);
}penghitung (10 huruf)
menghitung (10 huruf)
berulang (8 huruf)Lebih dari satu klausa from dapat ditulis ketika setiap elemen sumber membuka sumber lain. Tanpa kondisi penghubung, bentuk ini menghasilkan semua kombinasi, sebagaimana dua daftar berikut yang menyusun jadwal dari hari dan shift.
// Contoh: dua klausa from menghasilkan semua kombinasi hari dan shift
string[] hari = { "Senin", "Selasa" };
string[] shift = { "Pagi", "Sore" };
var kombinasi =
from h in hari
from s in shift
select $"{h} shift {s}";
foreach (string baris in kombinasi)
{
Console.WriteLine(baris);
}Senin shift Pagi
Senin shift Sore
Selasa shift Pagi
Selasa shift SoreKlausa select pada bentuk query juga boleh menghasilkan objek tanpa nama, misalnya select new { Kata = kata, Panjang = panjang }, sehingga satu query dapat mengemas beberapa nilai sekaligus. Bentuk ini setara dengan proyeksi Select pada sintaks metode dan berguna ketika laporan memerlukan lebih dari satu kolom. Pemilihan bentuk keluaran pada kedua sintaks mengikuti kaidah yang sama, sehingga pengetahuan di satu sisi berpindah tanpa perlu belajar ulang.
Memilih antara sintaks metode dan query#
Kedua sintaks memiliki cakupan yang berbeda. Sintaks query hanya menyediakan klausa untuk sebagian operator, yaitu where, select, orderby, group, join, dan let, sedangkan operator seperti Count, First, dan Take hanya tersedia dalam bentuk metode. Tabel berikut merangkum kecenderungan keterbacaannya.
| Kondisi | Bentuk yang lebih mudah dibaca | Alasan |
|---|---|---|
| Penyaringan dan proyeksi sederhana | kedua bentuk setara | terjemahan kompilatornya identik |
| Alur baca menurut baris, misalnya saring lalu urutkan | query | klausa tersusun dari atas ke bawah |
| Perhitungan sementara yang digunakan berulang | query | klausa let memberi nama pada nilainya |
| Operator agregasi dan pengambilan satu elemen | metode | tidak ada padanan klausanya |
| Rantai operator pendek dengan lambda | metode | lebih ringkas daripada blok query |
Query dan metode juga boleh dicampur dalam satu ekspresi. Operator tanpa padanan klausa dipanggil langsung pada hasil query, sebagaimana Count dan Min pada contoh berikut.
Penilaian keterbacaan juga bergantung pada latar pembaca. Alur query yang tersusun dari atas ke bawah memudahkan penelusuran setiap tahapan penyaringan, sedangkan rantai metode yang pendek membuat fokus tetap pada lambda-nya, yaitu fungsi ringkas tanpa nama. Keputusan terbaik biasanya lahir dari konsistensi satu proyek, bukan dari selera tiap penulisnya.
// Contoh: operator tanpa padanan klausa ditulis dengan sintaks metode
List<int> nilaiUjian = new() { 84, 60, 90, 55, 75 };
int jumlahLulus = (
from n in nilaiUjian
where n >= 75
select n).Count();
Console.WriteLine($"Jumlah yang lulus: {jumlahLulus}");
Console.WriteLine($"Nilai terkecil yang lulus: {(
from n in nilaiUjian
where n >= 75
select n).Min()}");Jumlah yang lulus: 3
Nilai terkecil yang lulus: 75Contoh program utuh#
Program berikut merangkum seluruh bentuk query di atas dalam satu berkas.
// Program contoh bentuk query: from, where, select, orderby, let, dan from ganda
// Sumber data nilai ujian
List<int> nilaiUjian = new() { 84, 60, 90, 55, 75 };
// Bentuk query setara dengan Where dan Select pada sintaks metode
IEnumerable<int> lulusQuery =
from n in nilaiUjian
where n >= 75
select n;
Console.WriteLine($"Nilai yang lulus: {string.Join(", ", lulusQuery)}");
// orderby descending dan select ekspresi
var laporan =
from n in nilaiUjian
where n >= 75
orderby n descending
select $"Nilai {n} dinyatakan lulus";
foreach (string baris in laporan)
{
Console.WriteLine(baris);
}
// let menyimpan hasil perhitungan sementara
string kalimat = "penghitung kata menghitung kata yang berulang";
var kataPanjang =
from kata in kalimat.Split(' ')
let panjang = kata.Length
where panjang > 5
select $"{kata} ({panjang} huruf)";
foreach (string baris in kataPanjang)
{
Console.WriteLine(baris);
}
// dua klausa from membentuk semua kombinasi
string[] hari = { "Senin", "Selasa" };
string[] shift = { "Pagi", "Sore" };
var kombinasi =
from h in hari
from s in shift
select $"{h} shift {s}";
foreach (string baris in kombinasi)
{
Console.WriteLine(baris);
}
// operator tanpa padanan klausa ditulis dengan sintaks metode
int jumlahLulus = (
from n in nilaiUjian
where n >= 75
select n).Count();
Console.WriteLine($"Jumlah yang lulus: {jumlahLulus}");Nilai yang lulus: 84, 90, 75
Nilai 90 dinyatakan lulus
Nilai 84 dinyatakan lulus
Nilai 75 dinyatakan lulus
penghitung (10 huruf)
menghitung (10 huruf)
berulang (8 huruf)
Senin shift Pagi
Senin shift Sore
Selasa shift Pagi
Selasa shift Sore
Jumlah yang lulus: 3Jalankan 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
Nilai 90 dinyatakan lulus
Nilai 84 dinyatakan lulus
Nilai 75 dinyatakan lulus
penghitung (10 huruf)
menghitung (10 huruf)
berulang (8 huruf)
Senin shift Pagi
Senin shift Sore
Selasa shift Pagi
Selasa shift Sore
Jumlah yang lulus: 3Kesalahan umum#
- Melupakan klausa
selectdi akhir query. Bentuk query mewajibkannya, sehingga query yang diakhiriwheresaja ditolak kompilator dengan pesan pemilih yang kurang. - Mengira sintaks query berjalan lebih cepat karena tampaknya lebih dekat dengan database. Kedua bentuk diterjemahkan menjadi pemanggilan metode yang sama, sehingga performanya identik.
- Mencari padanan klausa untuk operator seperti
CountdanFirst. Padanan itu tidak ada, dan operator tersebut dipanggil sebagai metode pada hasil query. - Menuliskan pemisah titik koma di antara klausa. Klausa query dipisahkan baris baru atau spasi, sedangkan titik koma milik sintaks metode.
Ringkasan#
- Sintaks query menulis LINQ dengan klausa
from,where, danselect, lalu diterjemahkan kompilator menjadi pemanggilan metode yang setara dengan sintaks metode. - Klausa
orderby,let, danfromganda menambah pengurutan, variabel sementara, dan kombinasi antarsumber. - Sintaks query dan metode memiliki performa yang sama, sedangkan pilihannya ditentukan keterbacaan dan ketersediaan klausa.
- Operator tanpa padanan klausa dipanggil sebagai metode pada hasil query, sehingga kedua bentuk dapat dicampur.
Referensi#
- Write LINQ queries in C# — Microsoft Learn — Panduan resmi menulis query LINQ, termasuk hubungan sintaks query dan metode.
- Introduction to LINQ queries — Microsoft Learn — Penjelasan struktur query dan terjemahan klausanya ke metode.
- Grouping data — Microsoft Learn
— Dokumentasi operator pengelompokan yang padanannya berupa klausa
group.