次の方法で共有


NULL 比較

データ ソースの null 値は、値が不明であることを示します。 LINQ to Entities クエリでは、null 値をチェックして、特定の計算または比較が有効なデータまたは null 以外のデータを持つ行に対してのみ実行されるようにすることができます。 ただし、CLR の null セマンティクスは、データ ソースの null セマンティクスとは異なる場合があります。 ほとんどのデータベースでは、3 つの値を持つロジックのバージョンを使用して null 比較を処理します。 つまり、null 値に対する比較は、 true または falseに評価されず、 unknownに評価されます。 多くの場合、これは ANSI null の実装ですが、必ずしもそうであるとは限りません。

SQL Server の既定では、null-equals-null 比較では null 値が返されます。 次の例では、 ShipDate が null の行は結果セットから除外され、Transact-SQL ステートメントは 0 行を返します。

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

これは CLR の null セマンティクスとは大きく異なり、null-equals-null 比較では true が返されます。

次の LINQ クエリは CLR で表されますが、データ ソースで実行されます。 CLR セマンティクスがデータ ソースで受け入れられる保証がないため、予期される動作は不確定です。

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

キー セレクター

キー セレクターは、要素からキーを抽出するために標準クエリ演算子で使用される関数です。 キー セレクター関数では、式を定数と比較できます。 式が null 定数と比較される場合、または 2 つの null 定数が比較される場合、CLR null セマンティクスが示されます。 データ ソース内の null 値を持つ 2 つの列を比較すると、ストアの null セマンティクスが表示されます。 キー セレクターは、 GroupByなどの多くのグループ化および順序付け標準クエリ演算子で見つかり、クエリ結果の順序付けまたはグループ化に使用されるキーを選択するために使用されます。

NULL オブジェクトの NULL プロパティ

Entity Framework では、null オブジェクトのプロパティは null です。 CLR で null オブジェクトのプロパティを参照しようとすると、 NullReferenceExceptionを受け取ります。 LINQ クエリに null オブジェクトのプロパティが含まれている場合、一貫性のない動作が発生する可能性があります。

たとえば、次のクエリでは、 NewProduct へのキャストがコマンド ツリー レイヤーで実行され、 Introduced プロパティが null になる可能性があります。 DateTime比較が true に評価されるように、データベースで null 比較が定義されている場合、行が含まれます。

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 のコレクションを集約関数に渡す

LINQ to Entities では、集計関数に IQueryable をサポートするコレクションを渡すと、集計操作がデータベースで実行されます。 メモリ内で実行されたクエリとデータベースで実行されたクエリの結果に違いがある可能性があります。 メモリ内クエリでは、一致がない場合、クエリは 0 を返します。 データベースでは、同じクエリが nullを返します。 null値が LINQ 集計関数に渡されると、例外がスローされます。 可能な null 値を受け入れるには、クエリ結果を受け取る型の型とプロパティを null 許容値型にキャストします。

こちらも参照ください