Sintaks Metode LINQ

LINQ melalui metode .Where, .Select, dan agregasi seperti .Count dan .Sum.

Daftar isi

Operasi LINQ juga dapat ditulis sebagai rangkaian pemanggilan metode dengan lambda sebagai argumennya, tanpa klausa From di awal. Topik ini membahas metode Where dan Select untuk penyaringan dan proyeksi, metode agregasi seperti Count, Sum, dan Average, metode pencarian First, FirstOrDefault, dan Any, serta kondisi ketika sintaks metode lebih praktis daripada sintaks query.

Lambda sebagai argumen metode#

Lambda (lambda) adalah fungsi tanpa nama yang ditulis sebaris pada tempat argumennya berada. Bentuknya Function(n) n.Skor >= 80, yaitu kata kunci Function, satu parameter, lalu ekspresi yang nilainya menjadi hasil kembalian. Tipe parameter tidak dituliskan karena compiler menyimpulkannya dari tipe deretan yang dilalui, sedangkan lambda yang tubuhnya lebih dari satu baris tetap tersedia untuk logika yang panjang.

vb
' tidak-dijalankan
Dim tinggi = nilai.Where(Function(n) n.Skor >= 80)
Dim nama = nilai.Select(Function(n) n.Nama)

Metode Where menuntut fungsi yang menerima satu elemen dan mengembalikan Boolean, sehingga lambda pertama pada contoh di atas sesuai. Metode Select menuntut fungsi yang mengubah satu elemen menjadi baris hasil, sehingga lambda kedua mengembalikan String. Ketidakcocokan tanda tangan ini ditolak compiler, dan aturan yang sama berlaku di balik klausa Where dan Select pada sintaks query karena keduanya diterjemahkan compiler menjadi pemanggilan metode yang sama persis.

Where dan Select dalam sintaks metode#

Program berikut mengulang penyaringan skor 80 ke atas dengan Where, lalu memproyeksikan setiap siswa menjadi teks ringkas dengan Select. Data dan syaratnya sama dengan program utama topik Sintaks Query LINQ.

vb Program.vb
Module Program

    Class NilaiUjian
        Public Property Nama As String
        Public Property Skor As Integer
    End Class

    Sub Main()
        Dim nilai As New List(Of NilaiUjian) From {
            New NilaiUjian With {.Nama = "Ali", .Skor = 88},
            New NilaiUjian With {.Nama = "Budi", .Skor = 72},
            New NilaiUjian With {.Nama = "Citra", .Skor = 95},
            New NilaiUjian With {.Nama = "Dewi", .Skor = 64},
            New NilaiUjian With {.Nama = "Eka", .Skor = 80},
            New NilaiUjian With {.Nama = "Fajar", .Skor = 58},
            New NilaiUjian With {.Nama = "Gita", .Skor = 90},
            New NilaiUjian With {.Nama = "Hana", .Skor = 76},
            New NilaiUjian With {.Nama = "Indra", .Skor = 88}
        }

        Dim tinggi = nilai.Where(Function(n) n.Skor >= 80)
        Dim ringkas = tinggi.Select(Function(n) $"{n.Nama}: {n.Skor}")

        For Each baris As String In ringkas
            Console.WriteLine(baris)
        Next
    End Sub

End Module
text Keluaran
Ali: 88
Citra: 95
Eka: 80
Gita: 90
Indra: 88

Rantai metodenya dibaca dari kiri ke kanan. Where menghasilkan deretan NilaiUjian yang lolos syarat, lalu Select mengubah setiap elemennya menjadi String berformat Nama: Skor. Hasil akhirnya bertipe IEnumerable(Of String) dan penelusurannya dengan For Each berjalan sama seperti hasil query. Keluarannya memuat lima baris, sebab lima siswa memperoleh skor 80 ke atas.

Agregasi: Count, Sum, dan Average#

Metode agregasi mengerjakan seluruh deretan sekaligus dan mengembalikan satu nilai. Count menghitung banyaknya elemen, Sum menjumlahkan isinya, Average merata-ratakannya, sedangkan Min dan Max mencari batas bawah dan atasnya. Program berikut merangkum pengeluaran bulanan yang disimpan pada array Decimal.

vb Contoh: agregasi atas pengeluaran bulanan
Module DemoAgregasi

    Sub Main()
        Dim pengeluaran() As Decimal = {850000D, 920000D, 780000D, 950000D}

        Console.WriteLine(pengeluaran.Count())
        Console.WriteLine(pengeluaran.Sum())
        Console.WriteLine(pengeluaran.Average())
        Console.WriteLine(pengeluaran.Min())
        Console.WriteLine(pengeluaran.Max())
    End Sub

End Module
text Keluaran
4
3500000
875000
780000
950000

Array tersebut berisi empat angka, sehingga Count menghasilkan 4 dan Sum menghasilkan 3500000. Metode Average membagi jumlah dengan banyaknya elemen dan menghasilkan 875000, sedangkan Min dan Max menampilkan 780000 serta 950000. Bentuk Count dengan argumen lambda menghitung hanya elemen yang lolos syarat, misalnya nilai.Count(Function(n) n.Skor >= 80) atas daftar NilaiUjian program utama topik ini, yang menghasilkan 5.

First, FirstOrDefault, dan Any#

Metode pencarian menjawab pertanyaan tentang keberadaan satu elemen. First mengembalikan elemen pertama yang lolos syarat, FirstOrDefault mengembalikan nilai bawaan tipe elemennya ketika tidak ada kecocokan, dan Any mengembalikan True bila terdapat sedikitnya satu kecocokan. Program berikut menerapkan ketiganya atas daftar NilaiUjian.

vb Contoh: First, FirstOrDefault, dan Any
Module DemoPencarian

    Class NilaiUjian
        Public Property Nama As String
        Public Property Skor As Integer
    End Class

    Sub Main()
        Dim nilai As New List(Of NilaiUjian) From {
            New NilaiUjian With {.Nama = "Ali", .Skor = 88},
            New NilaiUjian With {.Nama = "Budi", .Skor = 72},
            New NilaiUjian With {.Nama = "Citra", .Skor = 95},
            New NilaiUjian With {.Nama = "Dewi", .Skor = 64},
            New NilaiUjian With {.Nama = "Eka", .Skor = 80},
            New NilaiUjian With {.Nama = "Fajar", .Skor = 58},
            New NilaiUjian With {.Nama = "Gita", .Skor = 90},
            New NilaiUjian With {.Nama = "Hana", .Skor = 76},
            New NilaiUjian With {.Nama = "Indra", .Skor = 88}
        }

        Dim pertamaTinggi = nilai.First(Function(n) n.Skor >= 90)
        Console.WriteLine($"{pertamaTinggi.Nama}: {pertamaTinggi.Skor}")

        Dim skor100 = nilai.FirstOrDefault(Function(n) n.Skor = 100)
        Console.WriteLine(skor100 Is Nothing)

        Dim adaRemedial = nilai.Any(Function(n) n.Skor < 60)
        Console.WriteLine(adaRemedial)
    End Sub

End Module
text Keluaran
Citra: 95
True
True

First menemukan Citra sebagai siswa pertama dengan skor 90 ke atas dan tidak melanjutkan penelusurannya. Pencarian skor tepat 100 tidak menemukan apa pun, sehingga FirstOrDefault mengembalikan Nothing dan pemeriksaan Is Nothing mencetak True. Pemanggilan Any dengan syarat skor di bawah 60 juga menghasilkan True karena Fajar memperoleh skor 58.

Kapan sintaks metode lebih praktis#

Sintaks metode menjadi pilihan ketika operasinya tidak memiliki klausa padanan pada sintaks query. Pencarian First, uji keberadaan Any, dan agregasi bersyarat seperti Count(Function(n) ...) tidak memiliki klausa langsung, sehingga menulisnya dengan sintaks query menuntut klausa Aggregate yang lebih panjang. Sintaks query lebih nyaman ketika alurnya panjang dan bertingkat karena klausanya terbaca dari atas ke bawah, sedangkan rantai metode terbaca dari kiri ke kanan.

Kedua gaya dapat dipadukan dalam satu program. Query disusun terlebih dahulu, lalu operasi tanpa padanan klausa dipanggil sebagai metode pada hasilnya. Tabel berikut merangkum pilihan yang umum digunakan.

KebutuhanPilihan yang umum
Penyaringan dan proyeksi bertingkatSintaks query dengan From, Where, dan Select
Satu nilai ringkasan dari seluruh deretanSintaks metode dengan Count, Sum, atau Average
Uji keberadaan dan pengambilan satu elemenSintaks metode dengan Any, First, atau FirstOrDefault
Gabungan kedua bentukQuery disusun dahulu, lalu metode dipanggil pada hasilnya

Kesalahan umum#

Tiga kesalahan berikut paling sering muncul pada penggunaan sintaks metode. Semuanya berkait dengan tanda tangan metode dan tipe hasilnya.

  1. Memanggil First pada deretan yang tidak berisi kecocokan. InvalidOperationException terlempar dan program berhenti, sehingga pola FirstOrDefault dengan pemeriksaan Is Nothing lebih aman pada data yang kekosongannya wajar.
  2. Menuliskan lambda Where yang tidak mengembalikan Boolean. Lambda seperti Function(n) n.Nama mengembalikan String sehingga ditolak compiler, dan perbaikannya adalah menggunakan ekspresi perbandingan yang hasilnya benar atau salah.
  3. Menganggap hasil Where berupa List. Metode tersebut mengembalikan IEnumerable(Of T) yang menunggu penelusuran, sehingga pemanggilan anggota khas List seperti Remove pada hasilnya ditolak compiler. Bila List diperlukan, panggil ToList pada hasilnya.

Ringkasan#

  • Lambda Function(n) ekspresi membawa fungsi satu langkah langsung ke tempat argumennya, dan tipenya disimpulkan compiler dari deretan yang dilalui.
  • Where menyaring, Select memproyeksikan, sedangkan Count, Sum, Average, Min, dan Max merangkum deretan menjadi satu nilai.
  • First mengembalikan kecocokan pertama atau melempar error, FirstOrDefault mengembalikan Nothing ketika tidak ada kecocokan, dan Any menguji keberadaan satu kecocokan saja.
  • Sintaks metode dipilih untuk operasi tanpa padanan klausa, sedangkan alur bertingkat tetap nyaman ditulis dengan sintaks query.

Referensi#