Delen via


Null-vergelijkingen

Een null waarde in de gegevensbron geeft aan dat de waarde onbekend is. In LINQ naar entiteiten-query's kunt u controleren op null-waarden, zodat bepaalde berekeningen of vergelijkingen alleen worden uitgevoerd op rijen met geldige of niet-null-gegevens. CLR null-semantiek kan echter verschillen van de null-semantiek van de gegevensbron. De meeste databases gebruiken een versie van drie-waardelogica om null-vergelijkingen te verwerken. Dat wil gezegd dat een vergelijking met een null-waarde niet resulteert in true of false, dat resulteert in unknown. Dit is vaak een implementatie van ANSI nulls, maar dit is niet altijd het geval.

In SQL Server retourneert de vergelijking null-equals-null standaard een null-waarde. In het volgende voorbeeld worden de rijen waar ShipDate null is uitgesloten van de resultatenset en retourneert de Transact-SQL-instructie 0 rijen.

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

Dit verschilt van de clr-semantiek null, waarbij de vergelijking null-gelijk aan null waar retourneert.

De volgende LINQ-query wordt uitgedrukt in de CLR, maar wordt uitgevoerd in de gegevensbron. Omdat er geen garantie is dat CLR-semantiek wordt gehonoreerd bij de gegevensbron, is het verwachte gedrag onbepaald.

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

Sleutelkiezers

Een sleutelkiezer is een functie die wordt gebruikt in de standaardqueryoperators om een sleutel uit een element te extraheren. In de sleutelkiezerfunctie kan een expressie worden vergeleken met een constante. CLR null-semantiek wordt weergegeven als een expressie wordt vergeleken met een null-constante of als twee null-constanten worden vergeleken. Null-semantiek opslaan wordt weergegeven als twee kolommen met null-waarden in de gegevensbron worden vergeleken. Sleutelkiezers zijn te vinden in veel van de standaardqueryoperators voor groepering en volgorde, zoals GroupByen worden gebruikt om sleutels te selecteren waarmee de queryresultaten moeten worden gerangschikt of gegroepeerd.

Null-eigenschap voor een Null-object

In Entity Framework zijn de eigenschappen van een null-object null. Wanneer u probeert te verwijzen naar een eigenschap van een null-object in de CLR, ontvangt u een NullReferenceException. Wanneer een LINQ-query een eigenschap van een null-object omvat, kan dit leiden tot inconsistent gedrag.

In de volgende query wordt bijvoorbeeld de cast uitgevoerd NewProduct in de opdrachtstructuurlaag, wat kan leiden tot null-eigenschap Introduced . Als de database null-vergelijkingen zodanig heeft gedefinieerd dat de DateTime vergelijking waar is, wordt de rij opgenomen.

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-verzamelingen doorgeven aan statistische functies

Wanneer u in LINQ naar entiteiten een verzameling doorgeeft die ondersteuning biedt IQueryable voor een statistische functie, worden statistische bewerkingen uitgevoerd in de database. Er kunnen verschillen zijn in de resultaten van een query die in het geheugen is uitgevoerd en een query die in de database is uitgevoerd. Met een in-memory query retourneert de query nul als er geen overeenkomsten zijn. In de database retourneert nulldezelfde query. Als een null waarde wordt doorgegeven aan een statistische LINQ-functie, wordt er een uitzondering gegenereerd. Als u mogelijke null waarden wilt accepteren, cast u de typen en de eigenschappen van de typen die queryresultaten ontvangen naar null-waardetypen.

Zie ook