2016-08-15 16 views
3

次のコードのAny機能が失敗する理由はありますか?LINQ失敗していますか?

var orders = db.Order.Where(order => order.Item.Any()); 
foreach (var order in orders) 
{ 
    var first = order.Item.First(); // NullReferenceException thrown here: order.Item == null 
} 

たぶん私は単にここで何かを誤解していますが、それは私には思えるorder.Itemによる以前のAnyステートメントにnullになることはありません。

編集:私は式が評価され、そこToListを置くことによって延期されていないことを確認した場合、私は原因も私をバッフルなしのアイテムを持っていないorder.Item配列に別の例外を取得:

var orders = db.Order.Where(order => order.Item.Any()).ToList(); 
foreach (var order in orders) 
{ 
    var first = order.Item.First(); // System.InvalidOperationException thrown here: order.Item.Count == 0 
} 
+0

「order.Item'の種類は? –

+0

私のモデルの 'Item'テーブルに由来する' Item'です。注文は0からnまでです。 –

+0

あなたはEntityFrameworkを使用していますか? –

答えて

9

表現ordersを計算すると、になるので、がある場合は、db.OrderItemになります。foreachループに入るまでは、見つからないでしょう。

あなたはToList()呼び出しを追加することで何が起こっているかを見ることができます。

var orders = db.Order.Where(order => order.Item.Any()).ToList(); 

は今、例外がループの前にスローされます。

var orders = db.Order.Where(order => order.Item != null && order.Item.Any()); 

または

var orders = db.Order.Where(order => order?.Item.Any()); 

order.Item.Count == 0誤りがあることがあります。

あなたは、またはC#6の新しい?.構文を使用してWhere条件で明示的にnullチェックを追加することによってこの問題を解決することができます同じ性質の:Any()のチェックはDBレベルで行われ、First()の呼び出しは後で行われるため、ここでAny()が成功するまでには、First()と呼ぶ時間がなくなりました。

LoadWithのオプションをItemに追加することで問題を解決できるはずです。

+0

これはまさにこれが起こっていると思ったが、完全な話ではない。私はまだ 'Any'がどのように実行されるのかわからないので、質問を更新しましたが、項目なしの' order.Item'を持っています。 –

+0

@Protectorone私は基本的な問題は同じだと思う - チェックとロードは異なる時に実行されます。 'Item'を熱心に読み込むことでこれを解決できるはずです。 – dasblinkenlight

+0

実際に 'DataLoadOptions'と' LoadWidth'を使って問題を修正しました!この問題を事前に予測できる方法はありますか?私はLINQに必要なエンティティを自動的にロードするのに慣れています... –

4

この行:それは必要になるまで

var orders = db.Order.Where(order => order.Item.Any()); 

が実際に評価しないので、後で失敗するように見えます。

あなたが持つ行交換する場合:

var orders = db.Order.Where(order => order.Item.Any()).ToList(); 

を、あなたは、リストが生成されるときに、クエリが評価されるよう、すぐに故障が表示されます。

が持つ行に置き換えます

var orders = db.Order.Where(order => order.Item != null && order.Item.Any()); 

をし、それはあなたが思うよりも簡単でOK

+0

これはまだ間に合いません。自分のコードに 'ToList'を置くと、私が受け取っている新しい例外で質問を更新しました。 –

0

を動作するはずです。 definition of Enumerable.Anyによると、sourceがnullの場合、ArgumentNullExceptionがスローされます。

あなたのクラスにはOrder.Itemというプロパティがあります。あなたの注文の1つに、値がnullのアイテムがあります。あなたのコードは:

var orders = db.Order.Where(order => order.Item != null && order.Item.Any()); 
関連する問題