Share via


Null összehasonlítások

Az null adatforrás egyik értéke azt jelzi, hogy az érték ismeretlen. A LINQ–Entitások lekérdezésekben null értékeket kereshet, így bizonyos számítások vagy összehasonlítások csak érvényes vagy nem null értékű adatokkal rendelkező sorokon végezhetők el. A CLR null szemantikája azonban eltérhet az adatforrás null szemantikájaitól. A legtöbb adatbázis háromértékű logikát használ a null összehasonlítások kezeléséhez. Ez azt jelenti, hogy a null értékekkel való összehasonlítás nem kiértékeli true a null értéket, vagy falsea kiértékeli azt unknown. Gyakran ez az ANSI nullértékek implementálása, de nem mindig ez a helyzet.

Az SQL Serverben alapértelmezés szerint a null-egyenlő-null összehasonlítás null értéket ad vissza. Az alábbi példában a null értéket tartalmazó ShipDate sorok ki vannak zárva az eredményhalmazból, a Transact-SQL utasítás pedig 0 sort ad vissza.

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

Ez nagyon eltér a CLR null szemantikától, ahol a null-egyenlő-null összehasonlítás igaz értéket ad vissza.

A következő LINQ-lekérdezés a CLR-ben van kifejezve, de az adatforrásban lesz végrehajtva. Mivel a CLR szemantikája nem garantált az adatforrásban, a várt viselkedés határozatlan.

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 : {0}", 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

Kulcsválasztók

A kulcsválasztó olyan függvény, amelyet a standard lekérdezési operátorok használnak egy kulcs elemből való kinyerésére. A kulcsválasztó függvényben egy kifejezés összehasonlítható egy állandóval. A CLR null szemantikája akkor van kiállítva, ha egy kifejezést egy null állandóval hasonlítunk össze, vagy ha két null állandót hasonlítunk össze. A tároló null szemantikája akkor lesz látható, ha két, null értékű oszlopot hasonlít össze az adatforrásban. A kulcsválasztók számos szabványos lekérdezési operátor csoportosításában és sorrendjében találhatók, például GroupBya kulcsok kiválasztására, amelyekkel rendezheti vagy csoportosíthatja a lekérdezés eredményeit.

Null tulajdonság null objektumon

Az Entity Frameworkben a null objektum tulajdonságai null értékűek. Amikor null objektum tulajdonságára próbál hivatkozni a CLR-ben, NullReferenceExceptionegy . Ha egy LINQ-lekérdezés null objektum tulajdonságát foglalja magában, az inkonzisztens viselkedést eredményezhet.

A következő lekérdezésben például a parancsfarétegben történik a leadás NewProduct , ami azt eredményezheti, hogy a Introduced tulajdonság null értékű. Ha az adatbázis null összehasonlítást definiált úgy, hogy az DateTime összehasonlítás értéke igaz legyen, a sor is szerepelni fog.

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 gyűjtemények átadása összesítő függvényeknek

A LINQ-ban az entitások számára, amikor egy összesítő függvénynek támogatott IQueryable gyűjteményt ad át, az összesítő műveletek az adatbázisban lesznek végrehajtva. A memóriában végrehajtott lekérdezések és az adatbázisban végrehajtott lekérdezések eredményei között eltérések lehetnek. Memórián belüli lekérdezés esetén, ha nincsenek egyezések, a lekérdezés nullát ad vissza. Az adatbázisban ugyanaz a lekérdezés ad nullvissza. Ha egy null értéket egy LINQ-összesítő függvénynek ad át, a rendszer kivételt küld. A lehetséges null értékek elfogadásához adja meg a lekérdezési eredményeket fogadó típusok típusait és tulajdonságait null értékű értéktípusokra.

Lásd még