C# 在实体间循环时实体框架异常(但在使用ToList()时有效)
我有一个名为MyItems的实体表,该表中的每个项都有一个指向另一个表的外键。我只想循环遍历我的项并访问每个项的外键对象的字符串“Name”属性,如下所示:C# 在实体间循环时实体框架异常(但在使用ToList()时有效),c#,entity-framework,linq-to-entities,lazy-loading,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时,我得到一个InvalidOpera
foreach (var myItem in (from q in context.MyItems select q))
{
string testName = myItem.ForeignItem.Name
}
当我这样做时,ForeignItem为null,当我尝试访问ForeignItem时,我得到一个InvalidOperationException:
已存在与此命令关联的打开的DataReader,该命令
必须先关闭
但是-如果我改为这样调用ToList():
我的外键对象填充得很好。我意识到ToList()将非常昂贵,因为整个表将立即被检索。我怀疑延迟加载在幕后出了问题,但我的理解是,它应该在不调用ToList()
的情况下工作
我忽略了什么吗
编辑:我想可能是使用var
造成了问题,所以我尝试使用
foreach (MyItem myItem in (from q in context.MyItems select q))
{
// loop contents
}
相反,结果是一样的。除了保留为空的外键对象外,myItem
的属性将被填充
Edit#2:我在整个应用程序中只使用了一个对象上下文和一个Linq to Entities语句,因此我无法解释另一个DataReader在哪里运行。我还应该注意,此错误发生在循环中的第一个对象上,因此它不是由于检索到上一个项而导致的。您编写了
myItem
,而不是q
。您应该使用以下选项:
(from q in context.MyItems select q)
或者更简单地说,您可以这样写:
context.MyItems
关于更新的问题,这似乎是因为您在第一个查询完成之前启动了一个新查询。可能的解决办法:
- 运行原始查询时包含子项
foreach (var myItem in context.MyItems.Include("ForeignItem")) { ... }
- 启用MultipleActiveResultSet
- 您编写了
myItem
而不是q
。您应该使用以下选项:
(from q in context.MyItems select q)
或者更简单地说,您可以这样写:
context.MyItems
关于更新的问题,这似乎是因为您在第一个查询完成之前启动了一个新查询。可能的解决办法:
- 运行原始查询时包含子项
foreach (var myItem in context.MyItems.Include("ForeignItem")) { ... }
- 启用MultipleActiveResultSet
顺便提一下,将
MultipleActiveResultSets
设置为true也可以工作。现在,我将使用Include()
,因为应用程序很小,并且只有一条Linq语句。根据Mark的建议,我最后做的是:
顺便提一下,将
MultipleActiveResultSets
设置为true也可以工作。现在,我将使用Include()
,因为应用程序很小,并且只有一条Linq语句。我正在清理对象名称,因此,输入错误与问题无关。我已经更新了问题中的代码。是否也存在执行延迟的问题?IIRC,LINQ查询延迟执行,直到通过类似ToList/ToArray的方式对其进行操作。ForEach会强制执行吗?@kevinmajor1是的,ForEach
会强制执行。谢谢更新您的答案。Include()似乎只接受字符串参数。我怀疑那个代码不正确。我将尝试使用中指定的类型名称。我正在清理对象名称,因此,键入错误与问题无关。我已经更新了问题中的代码。是否也存在执行延迟的问题?IIRC,LINQ查询延迟执行,直到通过类似ToList/ToArray的方式对其进行操作。ForEach会强制执行吗?@kevinmajor1是的,ForEach
会强制执行。谢谢更新您的答案。Include()似乎只接受字符串参数。我怀疑那个代码不正确。我将尝试使用.Is ForeignItem.name中指定的类型名称。命名需要立即加载的内容?是否尝试放置myItem.ForeignItem.Load();在您实际尝试获取ForeignItem.Name值之前?@Brian应该加载它,句号。为什么它在我调用ToList()
时有效,而在我不调用时无效,这是一个大问题。@Jane Doe即使ForeignItem
公开了这样一个方法,ForeignItem
为null,所以我会在null对象上调用一个实例方法。所以myItem.ForeignItem不公开.Load();或者.loadForeignitmReference()?是ForeignItem.Name需要立即加载的内容吗?是否尝试放置myItem.ForeignItem.Load();在您实际尝试获取ForeignItem.Name值之前?@Brian应该加载它,句号。为什么它在我调用ToList()
时有效,而在我不调用时无效,这是一个大问题。@Jane Doe即使ForeignItem
公开了这样一个方法,ForeignItem
为null,所以我会在null对象上调用一个实例方法。所以myItem.ForeignItem不公开.Load();或.loadForeignitmReference()?