Porovnávání s hodnotou Null
null
Hodnota ve zdroji dat označuje, že hodnota je neznámá. V dotazech LINQ to Entities (LINQ to Entities) můžete zkontrolovat hodnoty null, aby se určité výpočty nebo porovnání prováděly pouze na řádcích, které mají platná nebo nenulová data. Sémantika clR null se však může lišit od sémantiky null zdroje dat. Většina databází používá k porovnání hodnot null verzi logiky se třemi hodnotami. To znamená, že porovnání s hodnotou null se nevyhodnocuje true
nebo false
, vyhodnocuje na unknown
. Často se jedná o implementaci hodnot NULL ANSI, ale nejedná se vždy o případ.
Ve výchozím nastavení v SYSTÉMU SQL Server vrátí porovnání s hodnotou null rovnou-null hodnotu null. V následujícím příkladu jsou řádky ShipDate
s hodnotou null vyloučeny ze sady výsledků a příkaz Transact-SQL vrátí 0 řádků.
-- 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
To se velmi liší od sémantiky CLR null, kde porovnání null-equals-null vrátí hodnotu true.
Následující dotaz LINQ se vyjadřuje v CLR, ale provádí se ve zdroji dat. Vzhledem k tomu, že neexistuje žádná záruka, že sémantika CLR bude dodržena ve zdroji dat, očekávané chování je neurčité.
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
Selektory klíčů
Selektor klíčů je funkce použitá ve standardních operátorech dotazu k extrakci klíče z elementu. Ve funkci selektoru klíčů lze výraz porovnat s konstantou. Sémantika CLR null se vykazuje, pokud je výraz porovnán s nulovou konstantou nebo pokud jsou porovnány dvě konstanty null. Pokud jsou ve zdroji dat porovnány dva sloupce s hodnotami null ve zdroji dat, zobrazí se sémantika s hodnotou null. Selektory klíčů se nacházejí v mnoha standardních operátorech seskupování a řazení standardních dotazů, například GroupBya slouží k výběru klíčů, podle kterých se mají výsledky dotazu seřadit nebo seskupit.
Vlastnost Null u objektu Null
Ve službě Entity Framework mají vlastnosti objektu null hodnotu null. Při pokusu o odkaz na vlastnost null objekt v CLR, obdržíte hodnotu NullReferenceException. Pokud dotaz LINQ zahrnuje vlastnost objektu null, může to vést k nekonzistentnímu chování.
Například v následujícím dotazu se přetypování NewProduct
provádí ve vrstvě stromu příkazů, což může vést k Introduced
tomu, že vlastnost má hodnotu null. Pokud databáze definovala porovnání s hodnotou null tak, aby DateTime se porovnání vyhodnocuje jako pravda, bude řádek zahrnut.
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
Předávání kolekcí null agregačním funkcím
Když v LINQ to Entities předáte kolekci, která podporuje IQueryable
agregační funkci, agregační operace se provádějí v databázi. Ve výsledcích dotazu, který byl proveden v paměti, a dotaz, který byl proveden v databázi, můžou být rozdíly. Pokud dotaz v paměti neobsahuje žádné shody, vrátí dotaz nulu. V databázi vrátí null
stejný dotaz . null
Pokud je hodnota předána agregační funkci LINQ, vyvolá se výjimka. Chcete-li přijmout možné null
hodnoty, přetypujte typy a vlastnosti typů, které přijímají výsledky dotazu na typy hodnot s možnou hodnotou null.