Null Karşılaştırmalar

null Veri kaynağındaki bir değer, değerin bilinmediğini gösterir. LINQ to Entities sorgularında, bazı hesaplamaların veya karşılaştırmaların yalnızca geçerli veya null olmayan veriler içeren satırlarda gerçekleştirilmesi için null değerleri de kontrol edebilirsiniz. Ancak CLR null semantiği, veri kaynağının null semantiğinden farklı olabilir. Çoğu veritabanı, null karşılaştırmaları işlemek için üç değerli mantığın sürümünü kullanır. Başka bir ifadeyle, null değerle yapılan bir karşılaştırma true veya false olarak değerlendirilmez, unknown olarak değerlendirilir. Bu genellikle ANSI null'larının bir uygulamasıdır, ancak her zaman böyle değildir.

SQL Server'da varsayılan olarak null-equals-null karşılaştırması bir null değer döndürür. Aşağıdaki örnekte null olan ShipDate satırlar sonuç kümesinden dışlanır ve Transact-SQL deyimi 0 satır döndürür.

-- 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

Bu, null-equals-null karşılaştırmasının true döndürdüğü CLR null semantiğinden çok farklıdır.

Aşağıdaki LINQ sorgusu CLR'de ifade edilir, ancak veri kaynağında yürütülür. CLR semantiğinin veri kaynağında kabul edileceğinin garantisi olmadığından beklenen davranış belirsizdir.

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

Anahtar Seçiciler

Anahtar seçici, standart sorgu işleçlerinde bir öğeden anahtar ayıklamak için kullanılan bir işlevdir. Anahtar seçici işlevinde bir ifade sabitle karşılaştırılabilir. Bir ifade null sabitle karşılaştırılırsa veya iki null sabit karşılaştırılırsa CLR null semantiği sergilenir. Veri kaynağında null değerlere sahip iki sütun karşılaştırılırsa depo null semantiği sergilenir. Anahtar seçiciler, gibi GroupBystandart sorgu işleçlerinin çoğunda bulunur ve sorgu sonuçlarını sıralamak veya gruplandırmak için anahtarları seçmek için kullanılır.

Null Nesnede Null Özelliği

Entity Framework'te, null nesnenin özellikleri null'tır. CLR'de null nesnenin bir özelliğine başvurmaya çalıştığınızda, bir NullReferenceExceptionalırsınız. LINQ sorgusu null bir nesnenin özelliğini içerdiğinde, bu tutarsız davranışa neden olabilir.

Örneğin, aşağıdaki sorguda, NewProduct dönüşümü komut ağacı katmanında yapılır ve bu, Introduced özelliğinin null olmasına neden olabilir. Eğer veritabanı, null karşılaştırmalarını DateTime karşılaştırmasının doğru olarak değerlendirilmesi şeklinde tanımladıysa, satır dahil edilir.

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

Null Koleksiyonları Toplama İşlevlerine Geçirme

LINQ to Entities içinde, bir toplama işlevini destekleyen IQueryable bir koleksiyon geçirdiğinizde, toplama işlemleri veritabanında gerçekleştirilir. Bellek içinde gerçekleştirilen bir sorgunun ve veritabanında gerçekleştirilen bir sorgunun sonuçlarında farklılıklar olabilir. Bellek içi sorguda eşleşme yoksa sorgu sıfır döndürür. Aynı sorgu, veritabanında null döndürüyor. LinQ toplama işlevine bir null değer geçirilirse bir özel durum oluşturulur. Olası null değerlerini kabul etmek için, sorgu sonuçlarını alan türler ve bu türlerin özelliklerini null atanabilir değer türlerine dönüştürün.

Ayrıca bkz.