Hubungan Jenis dalam Operasi Kueri (Visual Basic)

Variabel yang digunakan dalam operasi kueri Kueri Terintegrasi Bahasa (LINQ) berjenis kuat dan harus kompatibel satu sama lain. Penjenisan kuat digunakan dalam sumber data, dalam kueri itu sendiri, dan dalam eksekusi kueri. Ilustrasi berikut mengidentifikasi istilah yang digunakan untuk menjelaskan kueri LINQ. Untuk informasi selengkapnya tentang bagian kueri, lihat Operasi Kueri Dasar (Visual Basic).

Screenshot showing a pseudocode query with elements highlighted.

Jenis variabel rentang dalam kueri harus kompatibel dengan jenis elemen dalam sumber data. Jenis variabel kueri harus kompatibel dengan elemen urutan yang ditentukan dalam klausul Select. Terakhir, jenis elemen urutan juga harus kompatibel dengan jenis variabel kontrol perulangan yang digunakan dalam pernyataan For Each yang menjalankan kueri. Penjenisan kuat ini memfasilitasi identifikasi kesalahan jenis pada waktu kompilasi.

Visual Basic membuat penjenisan kuat mudah dengan menerapkan inferensi jenis lokal, yang juga dikenal sebagai penjenisan tersirat. Fitur tersebut digunakan dalam contoh sebelumnya, dan Anda akan melihatnya digunakan di sepanjang sampel dan dokumentasi LINQ. Dalam Visual Basic, inferensi jenis lokal dicapai hanya dengan menggunakan pernyataan Dim tanpa klausul As. Dalam contoh berikut, city berjenis kuat sebagai string.

Dim city = "Seattle"

Catatan

Inferensi jenis lokal hanya berfungsi saat Option Infer diatur ke On. Untuk informasi selengkapnya lihat Pernyataan Kesimpulan Opsi.

Akan tetapi, meski Anda menggunakan inferensi jenis lokal dalam kueri, hubungan jenis yang sama dihadirkan di antara variabel dalam sumber data, variabel kueri, dan perulangan eksekusi kueri. Ada gunanya untuk memiliki pemahaman dasar tentang hubungan jenis ini jika Anda menulis kueri LINQ, atau menggunakan sampel dan contoh kode dalam dokumentasi.

Anda mungkin perlu menentukan jenis tersurat untuk variabel rentang yang tidak cocok dengan jenis yang ditampilkan dari sumber data. Anda dapat menentukan jenis variabel rentang dengan menggunakan klausul As. Akan tetapi, ini menghasilkan kesalahan jika konversi adalah konversi penyempitan dan Option Strict diatur ke On. Oleh karena itu, sebaiknya Anda melakukan konversi pada nilai yang diambil dari sumber data. Anda dapat mengonversi nilai dari sumber data menjadi jenis variabel rentang tersurat dengan menggunakan metode Cast. Anda juga dapat mentransmisikan nilai yang dipilih dalam klausul Select ke jenis tersurat yang berbeda dari jenis variabel rentang. Poin-poin ini diilustrasikan dalam kode berikut.

Dim numbers1() As Integer = {1, 2, 4, 16, 32, 64}
Dim numbers2() As Double = {5.0#, 10.0#, 15.0#}

' This code does not result in an error.
Dim numberQuery1 = From n As Integer In numbers1 Where n > 5

' This code results in an error with Option Strict set to On. The type Double
' cannot be implicitly cast as type Integer.
Dim numberQuery2 = From n As Integer In numbers2 Where n > 5

' This code casts the values in the data source to type Integer. The type of
' the range variable is Integer.
Dim numberQuery3 = From n In numbers2.Cast(Of Integer)() Where n > 5

' This code returns the value of the range variable converted to Integer. The type of
' the range variable is Double.
Dim numberQuery4 = From n In numbers2 Where n > 5 Select CInt(n)

Kueri yang Menampilkan Keseluruhan Elemen Data Sumber

Contoh berikut menunjukkan operasi kueri LINQ yang menampilkan urutan elemen yang dipilih dari data sumber. Sumber, names, berisi array string, dan keluaran kueri adalah urutan yang berisi string yang dimulai dengan huruf M.

Dim names = {"John", "Rick", "Maggie", "Mary"}
Dim mNames = From name In names
             Where name.IndexOf("M") = 0
             Select name

For Each nm In mNames
    Console.WriteLine(nm)
Next

Ini setara dengan kode berikut, tetapi jauh lebih singkat dan lebih mudah ditulis. Pengandalan inferensi jenis lokal dalam kueri adalah gaya yang disukai dalam Visual Basic.

Dim names2 = {"John", "Rick", "Maggie", "Mary"}
Dim mNames2 As IEnumerable(Of String) =
    From name As String In names
    Where name.IndexOf("M") = 0
    Select name

For Each nm As String In mNames
    Console.WriteLine(nm)
Next

Hubungan berikut ada dalam kedua contoh kode sebelumnya, baik saat jenis ditentukan secara tersirat atau tersurat.

  1. Jenis elemen dalam sumber data, names, merupakan jenis variabel rentang, name, dalam kueri.

  2. Jenis objek yang dipilih, name, menentukan jenis variabel kueri, mNames. Di sini name adalah string, sehingga variabel kueri adalah IEnumerable(Of String) dalam Visual Basic.

  3. Kueri yang ditentukan dalam mNames dijalankan dalam perulangan For Each. Perulangan mengulang hasil eksekusi kueri. Karena mNames, ketika dijalankan, akan menampilkan urutan string, variabel iterasi perulangan, nm, juga berupa string.

Kueri yang Menampilkan Satu Bidang dari Elemen Terpilih

Contoh berikut menunjukkan operasi kueri LINQ untuk SQL yang menampilkan urutan yang hanya berisi satu bagian dari setiap elemen yang dipilih dari sumber data. Kueri mengambil kumpulan objek Customer sebagai sumber datanya dan hanya memproyeksikan properti Name dalam hasilnya. Karena nama konsumen adalah string, kueri menghasilkan urutan string sebagai keluaran.

' Method GetTable returns a table of Customer objects.
Dim customers = db.GetTable(Of Customer)()
Dim custNames = From cust In customers
                Where cust.City = "London"
                Select cust.Name

For Each custName In custNames
    Console.WriteLine(custName)
Next

Hubungan antar variabel adalah seperti yang ada dalam contoh yang lebih sederhana.

  1. Jenis elemen dalam sumber data, customers, merupakan jenis variabel rentang, cust, dalam kueri. Dalam contoh ini, jenis tersebut adalah Customer.

  2. Pernyataan Select menampilkan properti Name dari setiap objek Customer alih-alih seluruh objek. Karena Name adalah string, variabel kueri, custNames, akan kembali menjadi IEnumerable(Of String), bukan Customer.

  3. Karena custNames mewakili urutan string, variabel iterasi perulangan For Each, custName, juga harus berupa string.

Tanpa inferensi jenis lokal, contoh sebelumnya akan lebih rumit untuk ditulis dan dipahami, seperti yang ditunjukkan oleh contoh berikut.

' Method GetTable returns a table of Customer objects.
 Dim customers As Table(Of Customer) = db.GetTable(Of Customer)()
 Dim custNames As IEnumerable(Of String) =
     From cust As Customer In customers
     Where cust.City = "London"
     Select cust.Name

 For Each custName As String In custNames
     Console.WriteLine(custName)
 Next

Kueri yang Memerlukan Jenis Anonim

Contoh berikut menunjukkan situasi yang lebih kompleks. Dalam contoh sebelumnya, tidak mudah untuk menentukan jenis untuk semua variabel secara tersurat. Dalam contoh ini, itu mustahil. Alih-alih memilih keseluruhan elemen Customer dari sumber data, atau satu bidang dari setiap elemen, klausul Select dalam kueri ini menampilkan dua properti objek Customer asli : Name dan City. Untuk merespons klausul Select, pengompilasi menentukan jenis anonim yang berisi dua properti tersebut. Hasil eksekusi nameCityQuery dalam perulangan For Each adalah kumpulan instans dari jenis anonim baru. Karena jenis anonim tidak memiliki nama yang dapat digunakan, Anda tidak dapat menentukan jenis nameCityQuery atau custInfo secara tersurat. Artinya, dengan jenis anonim, Anda tidak memiliki nama jenis untuk digunakan sebagai pengganti String dalam IEnumerable(Of String). Untuk informasi selengkapnya, lihat Jenis Anonim.

' Method GetTable returns a table of Customer objects.
Dim customers = db.GetTable(Of Customer)()
Dim nameCityQuery = From cust In customers
                    Where cust.City = "London"
                    Select cust.Name, cust.City

For Each custInfo In nameCityQuery
    Console.WriteLine(custInfo.Name)
Next

Meski tidak dimungkinkan untuk menentukan jenis untuk semua variabel dalam contoh sebelumnya, hubungannya tetap sama.

  1. Jenis elemen dalam sumber data sekali lagi merupakan jenis variabel rentang dalam kueri. Dalam contoh ini, cust adalah instans dari Customer.

  2. Karena pernyataan Select menghasilkan jenis anonim, variabel kueri, nameCityQuery, harus berjenis secara tersirat sebagai jenis anonim. Jenis anonim tidak memiliki nama yang dapat digunakan, dan oleh karena itu tidak dapat ditentukan secara tersurat.

  3. Jenis variabel iterasi dalam perulangan For Each adalah jenis anonim yang dibuat di langkah 2. Karena jenisnya tidak memiliki nama yang dapat digunakan, jenis variabel iterasi perulangan harus ditentukan secara tersirat.

Lihat juga