1

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

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

当我这样做时,ForeignItem 为空,并且当我尝试访问 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 在哪里运行。我还应该注意,这个错误发生在循环中的第一个对象上,所以它不是因为检索到前一个项目。

4

2 回答 2

5

你写myItem而不是q. 你应该使用这个:

(from q in context.MyItems select q)

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

context.MyItems

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

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

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

有关的

于 2012-08-08T18:28:41.620 回答
0

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

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

顺便说一句,设置MultipleActiveResultSets为 true 也可以。现在,我将使用它,Include()因为应用程序很小并且其中只有一个 Linq 语句。

于 2012-08-08T19:23:15.757 回答