循环实体时的实体框架异常(虽然使用ToList()时工作)

时间:2012-08-08 18:27:29

标签: c# entity-framework linq-to-entities lazy-loading

我有一个名为MyItems的实体表,该表中的每个项都有一个外键到另一个表。我想简单地遍历我的项目并访问每个项目的外键对象的字符串'Name'属性,如下所示:

foreach (var myItem in (from q in context.MyItems select q))
{
   string testName = myItem.ForeignItem.Name
}

当我这样做时,ForeignItem为null,当我尝试访问ForeignItem时,我得到一个InvalidOperationException:

  

已经有一个与此命令关联的开放DataReader   必须先关闭。

然而 - 如果我改为调用ToList():

(from q in context.MyItems select q).ToList()

我的外键对象填充得很好。我意识到ToList()会很昂贵,因为整个表将立即被检索。我怀疑在延迟加载的情况下幕后出现问题,但我正在理解它 应该工作而不调用ToList()

我忽略了什么吗?

编辑:我在考虑使用var可能导致问题,所以我尝试使用

foreach (MyItem myItem in (from q in context.MyItems select q))
{
   // loop contents
}

相反 - 结果相同。除了保留为空的外键对象外,将填充myItem的属性。

编辑#2:我只在整个应用程序中使用一个对象上下文和一个Linq-to-Entities语句,所以我无法解释其他DataReader在哪里运行。我还应该注意,这个错误发生在循环中的第一个对象,所以它不是因为检索了前一个项目。

2 个答案:

答案 0 :(得分:5)

你写了myItem而不是q。你应该用这个:

(from q in context.MyItems select q)

或者更简单地说,你可以写下这个:

context.MyItems

关于您更新的问题,似乎是因为您在第一个完成执行之前启动了新查询。可能的解决方案:

  • 运行原始查询时包括子项。

    foreach (var myItem in context.MyItems.Include("ForeignItem")) { ... }
    
  • 启用MultipleActiveResultSets。

相关

答案 1 :(得分:0)

根据马克关于使用Include( )的建议,这就是我最终要做的事情:

(from q in context.MyItems.Include("ForeignItemOne").Include("ForeignItemTwo").Include("ForeignItemThree") select q)

很明显,将MultipleActiveResultSets设置为true也可以。现在,我将使用Include(),因为应用程序很小,只有一个Linq语句。