Terjemahan Operator Kueri Standar
LINQ untuk SQL menerjemahkan Operator Kueri Standar untuk perintah SQL. Prosesor kueri database menentukan semantik eksekusi terjemahan SQL.
Operator Kueri Standar didefinisikan terhadap urutan. Urutan diurutkan dan bergantung pada identitas referensi untuk setiap elemen urutan. Untuk informasi selengkapnya, lihat Gambaran Umum Operator Kueri Standar (C#) atau Gambaran Umum Operator Kueri Standar (Visual Basic).
SQL terutama berkaitan dengan kumpulan nilai yang tidak diurutkan. Pengurutan biasanya merupakan operasi pasca-pemrosesan yang dinyatakan secara eksplisit yang diterapkan ke hasil akhir kueri daripada hasil menengah. Identitas ditentukan oleh nilai. Untuk alasan ini, kueri SQL dipahami untuk menangani multiset (tas) alih-alih kumpulan.
Paragraf berikut menjelaskan perbedaan antara Operator Kueri Standar dan terjemahan SQL untuk penyedia SQL Server bagi LINQ untuk SQL.
Dukungan Operator
Concat
Metode Concat ini didefinisikan untuk multiset yang diurutkan tempat urutan penerima dan urutan argumen sama. Concat bekerja sebagai UNION ALL
atas multiset diikuti dengan urutan umum.
Langkah terakhir adalah mengurutkan dalam SQL sebelum hasil diproduksi. Concat tidak mempertahankan urutan argumennya. Untuk memastikan pengurutan yang sesuai, Anda harus secara eksplisit mengurutkan hasil Concat.
Berpotongan, Kecuali, Persatuan
Metode Intersect dan Except hanya didefinisikan dengan baik pada kumpulan. Semantik untuk multiset tidak ditentukan.
Metode Union ini didefinisikan untuk multiset sebagai perangkaian multiset yang tidak diurutkan (secara efektif hasil klausul UNION ALL dalam SQL).
Ambil, Lewati
metode Take dan Skip didefinisikan dengan baik hanya terhadap kumpulan yang diurutkan. Semantik untuk kumpulan atau multiset yang tidak diurutkan tidak terdefinisi.
Catatan
Takedan Skip memiliki batasan tertentu ketika digunakan dalam kueri terhadap SQL Server 2000. Untuk informasi lebih lanjut, lihat entri “Lompati dan Gunakan Pengecualian pada SQL Server 2000” di Penyelesaian Masalah.
Karena keterbatasan pengurutan dalam SQL, LINQ untuk SQL mencoba memindahkan urutan argumen metode ini ke hasil metode. Contohnya, pertimbangkan kueri LINQ untuk SQL berikut:
var custQuery =
(from cust in db.Customers
where cust.City == "London"
orderby cust.CustomerID
select cust).Skip(1).Take(1);
Dim custQuery = _
From cust In db.Customers _
Where cust.City = "London" _
Order By cust.CustomerID _
Select cust Skip 1 Take 1
SQL yang dihasilkan untuk kode ini memindahkan pengurutan ke akhir, sebagai berikut:
SELECT TOP 1 [t0].[CustomerID], [t0].[CompanyName],
FROM [Customers] AS [t0]
WHERE (NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM (
SELECT TOP 1 [t1].[CustomerID]
FROM [Customers] AS [t1]
WHERE [t1].[City] = @p0
ORDER BY [t1].[CustomerID]
) AS [t2]
WHERE [t0].[CustomerID] = [t2].[CustomerID]
))) AND ([t0].[City] = @p1)
ORDER BY [t0].[CustomerID]
Menjadi jelas bahwa semua urutan yang ditentukan harus konsisten ketika Take dan Skip dirangkai bersama-sama. Jika tidak, hasilnya tidak terdefinisi.
Baik Take maupun Skip didefinisikan dengan baik untuk argumen integral non-negatif dan konstan didasarkan pada spesifikasi Operator Kueri Standar.
Operator Tanpa Terjemahan
Metode berikut tidak diterjemahkan oleh LINQ untuk SQL. Alasan paling umum adalah perbedaan antara multiset dan urutan yang tidak diurutkan.
Operator | Alasan |
---|---|
TakeWhile, SkipWhile | Kueri SQL beroperasi pada multiset, bukan pada urutan. ORDER BY harus menjadi klausul terakhir yang diterapkan pada hasil. Untuk alasan ini, tidak ada terjemahan tujuan umum untuk dua metode ini. |
Reverse | Terjemahan metode ini dimungkinkan untuk kumpulan yang diurutkan tetapi saat ini tidak diterjemahkan oleh LINQ untuk SQL. |
Last, LastOrDefault | Terjemahan metode ini dimungkinkan untuk kumpulan yang diurutkan tetapi saat ini tidak diterjemahkan oleh LINQ untuk SQL. |
ElementAt, ElementAtOrDefault | Kueri SQL beroperasi pada multiset, bukan pada urutan yang dapat diindeks. |
DefaultIfEmpty (kelebihan beban dengan argumen default) | Secara umum, nilai default tidak dapat ditentukan untuk tuple arbitrer. Nilai null untuk tuple dimungkinkan dalam beberapa kasus melalui gabungan luar. |
Terjemahan Ekspresi
Semantik null
LINQ untuk SQL tidak memberlakukan semantik perbandingan null pada SQL. Operator perbandingan secara sintaksis diterjemahkan ke SQL yang setara. Untuk alasan ini, semantik mencerminkan semantik SQL yang ditentukan oleh pengaturan server atau koneksi. Contohnya, dua nilai null dianggap tidak setara berdasarkan pengaturan SQL Server default, tetapi Anda dapat mengubah pengaturan untuk mengubah semantik. LINQ untuk SQL tidak mempertimbangkan pengaturan server ketika menerjemahkan kueri.
Perbandingan dengan null harfiah diterjemahkan ke versi SQL yang sesuai (is null
atau is not null
).
Nilai null
dalam kolase didefinisikan oleh SQL Server. LINQ untuk SQL tidak mengubah kolase.
Agregat
Metode agregat Sum Operator Kueri Standar mengevaluasi hingga nol untuk urutan kosong atau untuk urutan yang hanya memuat null. Dalam LINQ untuk SQL, semantik SQL dibiarkan tidak berubah, dan Sum mengevaluasi ke null
bukan nol untuk urutan kosong atau untuk urutan yang hanya memuat null.
Batasan SQL pada hasil antara berlaku untuk agregat di LINQ to SQL. Dari Sum jumlah bilangan bulat 32-bit tidak dihitung dengan menggunakan hasil 64-bit. Luapan dapat terjadi untuk LINQ untuk SQL terjemahan Sum, bahkan jika penerapan Operator Kueri Standar tidak menyebabkan luapan untuk urutan dalam memori yang sesuai.
Demikian juga, LINQ untuk SQL terjemahan Average nilai bilangan bulat dihitung sebagai integer
, bukan sebagai double
.
Argumen Entitas
LINQ untuk SQL mengaktifkan jenis entitas yang akan digunakan dalam metode GroupBy dan OrderBy. Dalam terjemahan operator ini, penggunaan argumen jenis dianggap setara dengan menentukan semua anggota jenis tersebut. Contohnya, kode berikut setara:
db.Customers.GroupBy(c => c);
db.Customers.GroupBy(c => new { c.CustomerID, c.ContactName });
db.Customers.GroupBy(Function(c) c)
db.Customers.GroupBy(Function(c) New With {c.CustomerID, _
c.ContactName})
Argumen yang Setara/Sebanding
Kesetaraan argumen diperlukan dalam penerapan metode berikut:
LINQ untuk SQL mendukung kesetaraan dan perbandingan untuk argumen datar, tetapi tidak untuk argumen yang atau memuat urutan. Argumen datar adalah jenis yang dapat dipetakan ke baris SQL. Proyeksi satu atau beberapa jenis entitas yang dapat ditentukan secara statis untuk tidak memuat urutan dianggap sebagai argumen datar.
Berikut adalah contoh argumen datar:
db.Customers.Select(c => c);
db.Customers.Select(c => new { c.CustomerID, c.City });
db.Orders.Select(o => new { o.OrderID, o.Customer.City });
db.Orders.Select(o => new { o.OrderID, o.Customer });
db.Customers.Select(Function(c) c)
db.Customers.Select(Function(c) New With {c.CustomerID, c.City})
db.Orders.Select(Function(o) New With {o.OrderID, o.Customer.City})
db.Orders.Select(Function(o) New With {o.OrderID, o.Customer})
Berikut adalah contoh argumen non-datar (hierarkis):
// In the following line, c.Orders is a sequence.
db.Customers.Select(c => new { c.CustomerID, c.Orders });
// In the following line, the result has a sequence.
db.Customers.GroupBy(c => c.City);
' In the following line, c.Orders is a sequence.
db.Customers.Select(Function(c) New With {c.CustomerID, c.Orders})
' In the following line, the result has a sequence.
db.Customers.GroupBy(Function(c) c.City)
Terjemahan Fungsi Visual Basic
Fungsi pembantu berikut yang digunakan oleh pengompilasi Visual Basic diterjemahkan ke operator dan fungsi SQL yang sesuai:
CompareString
DateTime.Compare
Decimal.Compare
IIf (in Microsoft.VisualBasic.Interaction)
Metode konversi:
ToBoolean
ToSByte
ToByte
ToChar
ToCharArrayRankOne
ToDate
ToDecimal
ToDouble
ToInteger
ToUInteger
ToLong
ToULong
ToShort
ToUShort
ToSingle
ToString
Dukungan Warisan
Pembatasan Pemetaan Warisan
Untuk mendapatkan informasi selengkapnya, lihat Cara: Memetakan Hierarki Warisan.
Pewarisan dalam Kueri
Konversi eksplisit C# hanya didukung dalam proyeksi. Konversi eksplisit yang digunakan di tempat lain tidak diterjemahkan dan diabaikan. Selain nama fungsi SQL, SQL benar-benar hanya melakukan yang setara dengan runtime bahasa umum (CLR) Convert. Artinya, SQL dapat mengubah nilai satu jenis ke jenis lainnya. Tidak ada yang setara dengan konversi eksplisit runtime bahasa umum karena tidak ada konsep menafsirkan kembali bit yang sama dengan jenis lain. Itu sebabnya konversi eksplisit C# hanya berfungsi secara lokal. Bukan jarak jauh.
Operator, is
dan as
, dan metode GetType
tidak terbatas pada operator Select
. Operator-operator tersebut juga dapat digunakan di operator kueri lain.
Dukungan SQL Server 2008
Dimulai dengan .NET Framework 3.5 SP1, LINQ untuk SQL mendukung pemetaan ke jenis tanggal dan waktu baru yang diperkenalkan dengan SQL Server 2008. Namun, ada beberapa batasan pada LINQ untuk SQL operator kueri yang dapat Anda gunakan ketika beroperasi terhadap nilai yang dipetakan ke jenis baru ini.
Operator Kueri yang Tidak Didukung
Operator kueri berikut tidak didukung pada nilai yang dipetakan ke jenis tanggal dan waktu SQL Server baru: DATETIME2
, , DATE
, TIME
, dan DATETIMEOFFSET
.
Aggregate
Average
LastOrDefault
OfType
Sum
Untuk mendapatkan informasi selengkapnya tentang pemetaan ke jenis tanggal dan waktu SQL Server ini, lihat Pemetaan Jenis SQL-runtime bahasa umum.
Dukungan SQL Server 2005
LINQ untuk SQL tidak mendukung fitur SQL Server 2005 berikut:
Prosedur tersimpan yang ditulis untuk SQL runtime bahasa umum.
Jenis yang ditetapkan pengguna.
Fitur kueri XML.
Dukungan SQL Server 2000
Batasan SQL Server 2000 berikut (dibandingkan dengan Microsoft SQL Server 2005) memengaruhi LINQ untuk dukungan SQL.
Operator Terapkan Silang dan Terapkan Luar
Operator-operator ini tidak tersedia di SQL Server 2000. LINQ untuk SQL mencoba serangkaian penulisan ulang untuk menggantinya dengan gabung yang sesuai.
Cross Apply
dan Outer Apply
dihasilkan untuk navigasi hubungan. Kumpulan kueri tempat penulisan ulang tersebut dimungkinkan tidak terdefinisi dengan baik. Untuk alasan ini, kumpulan kueri minimal yang didukung untuk SQL Server 2000 adalah kumpulan yang tidak melibatkan navigasi hubungan.
text / ntext
Jenis data text
/ ntext
tidak dapat digunakan dalam operasi kueri tertentu terhadap varchar(max)
/ nvarchar(max)
, yang didukung oleh Microsoft SQL Server 2005.
Tidak ada resolusi yang tersedia untuk batasan ini. Secara khusus, Anda tidak dapat menggunakan hasil Distinct()
yang memuat anggota yang dipetakan ke kolom text
atau ntext
.
Perilaku Yang Dipicu oleh Kueri Bersarang
Pengikat SQL Server 2000 (melalui SP4) memiliki beberapa idiosyncrasies yang dipicu oleh kueri bersarang. Kumpulan kueri SQL yang memicu idiosyncrasies ini tidak ditentukan dengan baik. Untuk alasan ini, Anda tidak dapat menentukan kumpulan LINQ untuk SQL kueri yang dapat menyebabkan pengecualian SQL Server.
Lompati dan Ambil Operator
Takedan Skip memiliki batasan tertentu ketika digunakan dalam kueri terhadap SQL Server 2000. Untuk informasi lebih lanjut, lihat entri “Lompati dan Gunakan Pengecualian pada SQL Server 2000” di Penyelesaian Masalah.
Materialisasi Objek
Materialisasi membuat objek runtime bahasa umum dari baris yang dikembalikan oleh satu atau beberapa kueri SQL.
Panggilan berikut dijalankan secara lokal sebagai bagian dari materialisasi:
Konstruktor
ToString
metode dalam proyeksiKetik konversi eksplisit dalam proyeksi
Metode yang mengikuti metode AsEnumerable telah dijalankan secara lokal. Metode ini tidak menyebabkan eksekusi segera.
Anda dapat menggunakan
struct
sebagai jenis hasil kueri yang dikembalikan atau sebagai anggota jenis hasil. Entitas harus menjadi kelas. Jenis anonim diwujudkan sebagai instans kelas, tetapi struktur bernama (non-entitas) dapat digunakan dalam proyeksi.Anggota dari jenis hasil kueri yang dikembalikan dapat berupa jenis IQueryable<T>. Ini diwujudkan sebagai kumpulan lokal.
Metode berikut menyebabkan materialisasi langsung dari urutan yang diterapkan pada metode: