Share via


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

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í nullstejný 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.

Viz také