Perbandingan Null

Nilai null dalam sumber data menunjukkan bahwa nilainya tidak diketahui. Dalam kueri LINQ ke Entitas, Anda dapat memeriksa nilai null sehingga perhitungan atau perbandingan tertentu hanya dilakukan pada baris yang memiliki data yang valid, atau non-null. Namun, semantik null CLR mungkin berbeda dari semantik null sumber data. Sebagian besar database menggunakan versi logika tiga nilai untuk menangani perbandingan null. Artinya, perbandingan terhadap nilai null tidak mengevaluasi ke true atau false, melainkan mengevaluasi ke unknown. Seringkali ini adalah implementasi dari ANSI null, tetapi ini tidak selalu terjadi.

Secara default di SQL Server, perbandingan null-equals-null mengembalikan nilai null. Dalam contoh berikut, baris di mana ShipDate null dikecualikan dari kumpulan hasil, dan pernyataan Transact-SQL akan mengembalikan 0 baris.

-- Find order details and orders with no ship date.
SELECT h.SalesOrderID
FROM Sales.SalesOrderHeader h
JOIN Sales.SalesOrderDetail o ON o.SalesOrderID = h.SalesOrderID
WHERE h.ShipDate IS Null

Ini sangat berbeda dari semantik null CLR, di mana perbandingan null-sama-dengan-null mengembalikan benar.

Kueri LINQ berikut dinyatakan dalam CLR, tetapi dijalankan di sumber data. Karena tidak ada jaminan bahwa semantik CLR akan dihormati di sumber data, perilaku yang diharapkan tidak ditentukan.

using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    ObjectSet<SalesOrderHeader> orders = context.SalesOrderHeaders;
    ObjectSet<SalesOrderDetail> details = context.SalesOrderDetails;

    var query =
        from order in orders
        join detail in details
        on order.SalesOrderID
        equals detail.SalesOrderID
        where order.ShipDate == null
        select order.SalesOrderID;

    foreach (var OrderID in query)
    {
        Console.WriteLine($"OrderID : {OrderID}");
    }
}
Using context As New AdventureWorksEntities()

    Dim orders As ObjectSet(Of SalesOrderHeader) = context.SalesOrderHeaders
    Dim details As ObjectSet(Of SalesOrderDetail) = context.SalesOrderDetails

    Dim query = _
        From order In orders _
        Join detail In details _
        On order.SalesOrderID _
        Equals detail.SalesOrderID _
        Where order.ShipDate = Nothing
        Select order.SalesOrderID


    For Each orderID In query
        Console.WriteLine("OrderID: {0} ", orderID)
    Next
End Using

Pemilih Kunci

Pemilih kunci adalah fungsi yang digunakan dalam operator kueri standar untuk mengekstrak kunci dari elemen. Dalam fungsi pemilih kunci, ekspresi dapat dibandingkan dengan konstanta. Semantik null CLR ditunjukkan jika ekspresi dibandingkan dengan konstanta null atau jika dua konstanta null dibandingkan. Semantik null pada penyimpanan ditampilkan ketika dua kolom dengan nilai null dibandingkan di sumber data. Selektor kunci ditemukan dalam banyak operator kueri standar pengelompokan dan pemesanan, seperti GroupBy, dan digunakan untuk memilih kunci untuk mengurutkan atau mengelompokkan hasil kueri.

Properti Null pada Objek Null

Dalam Entity Framework, properti dari objek null adalah null. Ketika Anda mencoba mereferensikan properti objek null di CLR, Anda akan menerima NullReferenceException. Saat kueri LINQ melibatkan properti objek null, ini dapat mengakibatkan perilaku yang tidak konsisten.

Misalnya, dalam kueri berikut, pengubahan tipe ke NewProduct dilakukan di lapisan pohon perintah, sehingga properti Introduced mungkin menjadi null. Jika database menetapkan perbandingan null sedemikian rupa sehingga perbandingan DateTime dievaluasi sebagai benar, baris tersebut akan disertakan.

using (AdventureWorksEntities context = new AdventureWorksEntities())
{

    DateTime dt = new DateTime();
    var query = context.Products
        .Where(p => (p as NewProduct).Introduced > dt)
        .Select(x => x);
}
Using context As New AdventureWorksEntities()
    Dim dt As DateTime = New DateTime()
    Dim query = context.Products _
        .Where(Function(p) _
            ((DirectCast(p, NewProduct)).Introduced > dt)) _
        .Select(Function(x) x)
End Using

Penerusan Koleksi Null ke Fungsi Agregat

Di LINQ ke Entitas, saat Anda meneruskan koleksi yang mendukung IQueryable ke fungsi agregat, operasi agregat dilakukan di database. Mungkin ada perbedaan dalam hasil kueri yang dilakukan dalam memori dan kueri yang dilakukan di database. Dengan kueri dalam memori, jika tidak ada kecocokan, kueri mengembalikan nol. Pada database, kueri yang sama mengembalikan null. Jika nilai null diteruskan ke fungsi agregat LINQ, pengecualian akan dilemparkan. Untuk menerima kemungkinan nilai null, transmisikan jenis dan properti tipe yang menerima hasil kueri ke jenis nilai nullable.

Lihat juga