背景
我正在根据父/子关系创建投影,其中包括父项的 Name 属性和子项的 Id 列表。
代码
private class ParentChildInfo
{
public string Name { get; set; }
public List<int> ChildIds { get; set; }
}
var infos = ctx.Masters.Include(m => m.Children).Select(
m => new ParentChildInfo()
{
Name = m.Name,
ChildIds = m.Children.Where(c => c.SomeProp.StartsWith("SpecialValue"))
.Select(c => c.Id).ToList()
}).ToList();
不幸的是,这产生了错误
LINQ to Entities does not recognize the method 'System.Collections.Generic.List`1[System.Int32] ToList[Int32]
这引导我到 this post ,建议 ( in the comments ) 进行以下更改:
private class ParentChildInfo
{
public string Name { get; set; }
public IEnumerable<int> ChildIds { get; set; } // No longer List<int>
}
var infos = ctx.Masters.Include(m => m.Children).Select(
m => new ParentChildInfo()
{
Name = m.Name,
ChildIds = m.Children.Where(c => c.SomeProp.StartsWith("SpecialValue"))
.Select(c => c.Id) // Dropped the .ToList()
}).ToList();
我最初想要获取列表而不是枚举,因为使用结果的代码运行了几分钟,而且我不想将 DbContext 占用那么长时间。
我使用这样的代码:
using (MyContext ctx = new MyContext())
{
// code from above that populates infoes
}
foreach (var info in infoes)
{
// use info.ChildIds
}
我计划移动 foreach
进入using
这样我就可以枚举 ChildId,但按 F5 并惊讶地发现代码有效。
问题
假设 DbContext 在此时已被处置,并且 ChildIds 是 IEnumerable<int>
而不是List<int>
,为什么我可以枚举 ChildIds?
最佳答案
这是因为ToList()
infos
的query 实际上执行查询。所以收藏ctx.Masters
被枚举并填充投影。即使没有 Include
它会注意到 Master.Children
被寻址并发出 SQL 连接。 IEnumerable<int> ChildIds
的实现类型可能是List<int>
.
关于entity-framework - DbContext 释放后枚举成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15667634/