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 false
a 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 null
vissza. 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.