Null-jämförelser
Ett null
värde i datakällan anger att värdet är okänt. I LINQ till entitetsfrågor kan du söka efter nullvärden så att vissa beräkningar eller jämförelser endast utförs på rader som har giltiga eller icke-null-data. CLR null-semantik kan dock skilja sig från datakällans null-semantik. De flesta databaser använder en version av trevärdeslogik för att hantera nulljämförelser. En jämförelse mot ett null-värde utvärderas alltså inte till true
eller false
, den utvärderas till unknown
. Detta är ofta en implementering av ANSI-nullvärden, men så är inte alltid fallet.
Som standard i SQL Server returnerar jämförelsen null-equals-null ett null-värde. I följande exempel undantas raderna där ShipDate
är null från resultatuppsättningen och Transact-SQL-instruktionen returnerar 0 rader.
-- 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
Detta skiljer sig mycket från CLR null-semantiken, där jämförelsen null-equals-null returnerar sant.
Följande LINQ-fråga uttrycks i CLR, men den körs i datakällan. Eftersom det inte finns någon garanti för att CLR-semantik kommer att respekteras vid datakällan är det förväntade beteendet obestämt.
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
Nyckelväljare
En nyckelväljare är en funktion som används i standardfrågeoperatorerna för att extrahera en nyckel från ett element. I nyckelväljarens funktion kan ett uttryck jämföras med en konstant. CLR null-semantik visas om ett uttryck jämförs med en null-konstant eller om två null-konstanter jämförs. Lagra null-semantik visas om två kolumner med null-värden i datakällan jämförs. Nyckelväljare finns i många av de grupperings- och ordningsföljdsoperatorer för vanliga frågor, till exempel GroupBy, och används för att välja nycklar som frågeresultaten ska sorteras efter eller grupperas efter.
Null-egenskap för ett Null-objekt
I Entity Framework är egenskaperna för ett null-objekt null. När du försöker referera till en egenskap för ett null-objekt i CLR får du en NullReferenceException. När en LINQ-fråga omfattar en egenskap för ett null-objekt kan detta resultera i inkonsekvent beteende.
I följande fråga görs till exempel casten till i kommandoträdlagret, vilket kan leda till NewProduct
Introduced
att egenskapen blir null. Om databasen har definierat nulljämförelser så att jämförelsen DateTime utvärderas till true inkluderas raden.
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
Skicka Null-samlingar till aggregerade funktioner
I LINQ till entiteter utförs aggregerade åtgärder i databasen när du skickar en samling som stöder IQueryable
till en aggregeringsfunktion. Det kan finnas skillnader i resultatet av en fråga som utfördes i minnet och en fråga som utfördes i databasen. Med en minnesintern fråga returnerar frågan noll om det inte finns några matchningar. I databasen returnerar null
samma fråga . Om ett null
värde skickas till en LINQ-mängdfunktion genereras ett undantag. Om du vill acceptera möjliga null
värden omvandlar du typerna och egenskaperna för de typer som tar emot frågeresultat till nullbara värdetyper.