C# 林克:有失败吗?

C# 林克:有失败吗?,c#,linq,any,C#,Linq,Any,以下代码中的any功能可能会失败,原因是什么 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
功能可能会失败,原因是什么

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
语句而为空

编辑:如果我通过在那里放置
ToList
来确保表达式已计算且未延迟,则由于
顺序,我会得到另一个异常。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
}

计算
订单
的表达式是延迟的,因此当
db.Order
中存在任何
null
时,只有在
foreach
循环中才能找到它们

通过添加
ToList()
调用,您可以看到发生了什么:

var orders = db.Order.Where(order => order.Item.Any()).ToList();
现在,异常将在循环之前抛出

您可以通过在
Where
条件中添加显式
null
检查,或使用新的
?。
C#6语法:

order.Item.Count==0
错误可能具有相同的性质:因为对
Any()
的检查是在数据库级别完成的,而对
First()
的调用发生在稍后的某个时间,所以在调用
First()
时,为
Any()
成功而存在的项很可能已经消失

您应该能够通过为
项添加
LoadWith
选项来解决此问题
此行:

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());
在生成列表时,当查询被评估时,您将立即看到失败

将线路替换为:

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

而且它应该能正常工作

它比你想象的要简单。 根据ArgumentNullException,如果源为null,则会引发该异常

您的类顺序具有属性Order.Item。您的订单中有一个项目的值为null。您的代码应该是:

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

订单项
的类型是什么?它是
,源于我的模型中的
表。订单可以有0到n个项目。您使用EntityFramework吗?“项目”不是一个结构,对吗?@Adil:不,我的模型代码是使用SQLMetal生成的。我原以为这正是发生的事情,但这还不是全部。我已经更新了我的问题,因为我仍然不知道如何执行
Any
,但是却有
order.Item
,没有任何项目。@Protectorone我认为根本问题是一样的-检查和加载在不同的时间执行。您应该能够通过急切地加载
项来解决此问题。使用
DataLoadOptions
LoadWidth
确实解决了此问题!我有没有办法事先预料到这个问题?我习惯于LINQ自动加载所需的任何实体…@Protectorone不幸的是,这是一种恶劣的情况,因为很难预测由于大量移动部件而导致的错误。在某种程度上,像这样的问题比预期的更容易解决。这还不完全正确。我已经更新了我的问题,如果我在代码中放入
ToList
,我会收到新的异常。