Data transaksi biasanya hanya menyimpan PelangganId, sementara nama pelanggan tersimpan di koleksi lain. Operator Join menggabungkan dua urutan melalui kunci yang cocok, setara dengan inner join pada SQL. Elemen yang tidak memiliki pasangan tidak ikut dalam hasil.
Inner Join dengan Operator Join #
Contoh berikut menggabungkan daftar transaksi dengan daftar pelanggan:
record Pelanggan(int Id, string Nama);
record Transaksi(int Id, int PelangganId, int Total);
List<Pelanggan> pelanggan = new()
{
new Pelanggan(1, "Budi"),
new Pelanggan(2, "Siti"),
new Pelanggan(3, "Andi")
};
List<Transaksi> transaksi = new()
{
new Transaksi(101, 2, 85000),
new Transaksi(102, 1, 120000),
new Transaksi(103, 2, 45000),
new Transaksi(104, 9, 60000)
};
var gabungan = transaksi.Join(
pelanggan,
t => t.PelangganId,
c => c.Id,
(t, c) => $"{t.Id}: {c.Nama} - {t.Total}");
foreach (string baris in gabungan)
{
Console.WriteLine(baris);
}Output yang Dihasilkan:
101: Siti - 85000
102: Budi - 120000
103: Siti - 45000Mari kita bedah baris demi baris:
transaksi.Join(pelanggan, ...):transaksimenjadi outer sequence danpelangganmenjadi inner sequence.t => t.PelangganId: outerKeySelector menentukan kunci sisi transaksi.c => c.Id: innerKeySelector menentukan kunci sisi pelanggan; pasangan dibentuk bila kedua kunci sama.(t, c) => $"...": result selector membentuk satu string hasil dari setiap pasangan yang cocok.- hasil: transaksi 104 tidak memiliki pelanggan bernomor 9 dan pelanggan
Anditidak memiliki transaksi, sehingga keduanya tidak muncul.
Padanan Query Expression dan GroupJoin #
Bentuk query expression dari contoh di atas adalah from t in transaksi join c in pelanggan on t.PelangganId equals c.Id select .... Perhatikan kata equals yang wajib ditulis untuk menghubungkan kedua kunci, bukan operator ==.
Bila setiap elemen outer harus tetap muncul meskipun tanpa pasangan, gunakan GroupJoin sebagai pola left join: setiap grup hasil berisi mungkin kosong, dan DefaultIfEmpty() menyediakan nilai cadangan untuk grup tanpa isi. Operator agregasi seperti Sum juga sering dipasangkan dengan GroupJoin untuk merangkum transaksi per pelanggan.
Dua sifat hasil Join perlu diingat. Hasil menjaga urutan elemen outer, sehingga baris keluar mengikuti urutan transaksi, sedangkan urutan elemen inner tidak menjamin apa pun bila satu kunci memiliki beberapa pasangan. Untuk kunci gabungan yang terdiri atas lebih dari satu field, gunakan anonymous type sebagai kunci kedua sisi, misalnya t => new { t.Gudang, t.Tanggal }, dan pastikan kedua selector membentuk urutan field yang sama persis.