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
,我会收到新的异常。