Cha*_*lts 1 c# linq-to-entities entity-framework lazy-loading
我有一个名为MyItems的实体表,该表中的每个项都有一个到另一个表的外键.我想简单地遍历我的项目并访问每个项目的外键对象的字符串'Name'属性,如下所示:
foreach (var myItem in (from q in context.MyItems select q))
{
string testName = myItem.ForeignItem.Name
}
Run Code Online (Sandbox Code Playgroud)
当我这样做时,ForeignItem为null,当我尝试访问ForeignItem时,我得到一个InvalidOperationException:
已经有一个与此命令关联的打开DataReader,必须先关闭它.
但是 - 如果我这样调用ToList():
(from q in context.MyItems select q).ToList()
Run Code Online (Sandbox Code Playgroud)
我的外键对象填充得很好.我意识到ToList()会很昂贵,因为整个表将立即被检索.我怀疑在延迟加载的幕后出现了问题,但我正在理解它应该在没有调用的情况下工作ToList().
我忽略了什么吗?
编辑:我在想也许是因为使用var导致了问题,所以我尝试使用
foreach (MyItem myItem in (from q in context.MyItems select q))
{
// loop contents
}
Run Code Online (Sandbox Code Playgroud)
相反 - 相同的结果.myItem除了保留为null的外键对象外,将填充属性.
编辑#2:我只在整个应用程序中使用一个对象上下文和一个Linq-to-Entities语句,因此我无法解释其他DataReader的运行位置.我还应该注意,这个错误发生在循环中的第一个对象,所以它不是因为前一个项被检索.
你写的myItem而不是q.你应该用这个:
(from q in context.MyItems select q)
Run Code Online (Sandbox Code Playgroud)
或者更简单地说,你可以这样写:
context.MyItems
Run Code Online (Sandbox Code Playgroud)
关于您更新的问题,似乎是因为您在第一个完成执行之前启动了新查询.可能的解决方案:
运行原始查询时包括子项.
foreach (var myItem in context.MyItems.Include("ForeignItem")) { ... }
Run Code Online (Sandbox Code Playgroud)启用MultipleActiveResultSets.
有关