我一直在看一个课程,作者提到如果你有一些可以说的话,请说:
var someQuery = dbContext.Table.Where(x => x.Name == "Mark");
然后尝试使用someQuery
迭代forEach
的结果,它保持数据库连接打开,直到整个forEach
结束,并且很多初学者开发者犯了这个错误在forEach
中做了很多逻辑。相反,她建议先预先调用toList()
,然后对内存中的集合执行forEach
。
我找不到任何关于此的参考,但实体框架会保持数据库处于打开状态,直到forEach
循环停止。我如何评估这是否真的符合性能?
答案 0 :(得分:5)
应用于ToList()
的{{1}}方法是一种扩展方法,您可以在带有.NET反编译器的System.core.dll中看到该方法;
该方法复制&#34;私有数组&#34;如果源是IQueryable<T>
,否则它将从源执行foreach循环。
ICollection<T>
的真实实现是IQueryable<T>
,而不是System.Data.Entity.Infrastructure.DbQuery<TResult>
。
因此,ICollection<T>
基本上使用ToList()
复制来源。
现在,它取决于实现,但是以EF核心为例,有一个Enumerator
class,您可以看到在处理类时Connection(foreach
)已关闭。
根据另一个answer和ms documentation,您应该尽快释放连接并使其在连接池中可用,从而关闭连接。
为每个唯一连接字符串创建连接池。创建池时,会创建多个连接对象并将其添加到池中,以满足最小池大小要求。根据需要将连接添加到池中,直到指定的最大池大小(默认值为100)。当关闭或处置时,连接将被释放回池中。
因此,如果您正在执行复杂操作或执行其他查询或foreach中的任何其他内容,则首选ToList。