sco*_*ttm 5 c# sql-server ienumerable
我的问题是关于SQL连接状态,负载等基于以下代码:
public IEnumberable<MyType> GetMyTypeObjects()
{
string cmdTxt = "select * from MyObjectTable";
using(SqlConnection conn = new SqlConnection(connString))
{
using(SqlCommand cmd = new SqlCommand(cmdTxt, conn))
{
conn.Open();
using(SqlDataReader reader = cmd.ExecuteReader())
{
while(reader.Read())
{
yield return Mapper.MapTo<MyType>(reader);
}
}
}
}
yield break;
}
Run Code Online (Sandbox Code Playgroud)
我可以看到这可能是一个问题,如果有许多进程在IEnumerable对象的迭代之间运行类似的代码,执行时间长,因为连接将打开更长时间等等.但是,这似乎也可能会降低CPU使用率在SQL服务器上,因为它只在使用IEnumerable对象时返回数据.它还降低了客户端上的内存使用量,因为客户端只需在其工作时加载一个MyType实例,而不是加载所有出现的MyType(通过迭代整个DataReader并返回List或其他内容).
您是否有任何实例可以想到您不希望以这种方式使用IEnumerable,或者您认为它完全适合的任何实例?
这会给SQL服务器带来什么样的负载?
这是你在自己的代码中使用的东西(除非提及NHibernate,Subsonic等)吗?
这不是我要遵循的模式.我不会像在锁定时那样担心服务器上的负载.遵循这种模式将数据检索过程集成到您的业务逻辑流程中,这似乎是一个全面解决问题的方法; 你不知道在迭代方面会发生什么,而你正在插入它.一次性检索您的数据,然后在关闭阅读器后允许客户端代码对其进行枚举.
我不会使用它,因为它隐藏了正在发生的事情,并且它可能会在没有适当处理的情况下留下数据库连接。
当您读取完最后一条记录后,连接对象将被关闭,如果您在此之前停止读取,连接对象将不会被释放。例如,如果您知道结果中始终有 10 条记录,并且只有一个循环从枚举器读取这 10 条记录,而不进行第十一次读取超出最后一项的 Read 调用,则连接不会正确关闭。另外,如果您只想使用结果的一部分,则无法在不读取其余记录的情况下关闭连接。
即使您正确地使用了枚举器的内置扩展,也可能会导致这种情况:
foreach (MyType item in GetMyTypeObjects().Take(10)) {
...
}
Run Code Online (Sandbox Code Playgroud)