【发布时间】:2014-12-13 05:11:23
【问题描述】:
我正在尝试加载具有一系列 MyObjectChild 对象的 MyObject。我的上下文对象默认启用 LazyLoading,我没有禁用它。我的代码中有以下查询:
public MyObject GetMyObject(string objectNumber)
{
List<MyObject> query = (from obj in Context.MyObjects
where obj.ObjectNumber == objectNumber
orderby obj.LastUpdateDate descending
select obj).ToList();
return query.FirstOrDefault();
}
这会将第一项作为对象返回。是的,我们想断开从数据库返回的对象,所以我希望这会返回 MyObject 并附加所有 MyObjectChild 对象。尴尬的部分是数据库有数以千计的 MyObjectChilds,但是一旦在一个蓝月亮它决定不加载它们。
在代码的后面,我有:
MyObject myObject = GetMyObject("123456");
foreach (MyObjectChild c in myObject.MyObjectChilds)
{
... /* Do some stuff */
}
非常随机(一百分之一??)这个 foreach 循环没有任何要“foreach”的记录。请注意,它也不会引发异常!它只是完全绕过这部分代码,就好像 MyObjectChilds 集合是空的一样。
1) 谁能解释为什么会发生这种情况? 99% 的情况下,它都能正常工作,但当它失败时,对我们来说非常糟糕。我需要了解在什么情况下这可能会失败,以便我可以围绕它进行编码。
2) 防止这种情况/情况的最佳方法是什么? 我们到处都在做这种事情,而且我们的数据库布局很大,所以我宁愿不要偷懒加载并且必须重写我们所有的底层代码以在整个地方使用数千个 .Include(...) 语句。是否有更好/更简单/更快的解决方案仍能保证我们每次都能获得信息?
更新
在进行了更多挖掘之后,我找到了两个“半简单”的解决方案来解决这个问题。我知道但忽略了一个:ToList()。是的,我在查询上执行了ToList(),但我没有在foreach 上执行此操作,因此它有机会不加载子对象。
foreach (MyObjectChild c in myObject.MyObjectChilds.ToList())
{
另一个像.ToList() 一样非常工作的解决方案是在每次使用之前强制加载子对象。这对我来说实现起来会更加麻烦(基于我当前的代码)。但是,(从我从 SO 周围的其他帖子中可以看出)这更有可能总是得到我正在寻找的结果。
if (!obj.MyObjectChilds.IsLoaded)
{
obj.MyObjectChilds.Load();
}
foreach (MyObjectChild c in myObject.MyObjectChilds)
{
...
现在,我正在检查我的代码,以确保我已经 ToList-ed 我所有的循环子数据库对象的 foreach 循环。这似乎是最简单的解决方法,尽管我不确定它是否是“最正确”的解决方法。
【问题讨论】:
-
这听起来像是一个超时错误被抛出,可能被捕获但未处理。
-
我有一个 try/catch 和一个通用的 catch(异常)。它从不进入那段代码。
-
你实际上不需要
ToList,因为FirstOrDefault将返回结果。并不是说我认为这会解决任何问题。 -
很高兴知道。 :) 谢谢。
-
你为什么不用
Include()?
标签: c# linq linq-to-sql entity-framework-4