我的问题是有关基于以下代码的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;
}

如果有许多进程在IEnumerable对象的两次迭代之间运行相似代码且执行时间较长,因为连接将被打开得更长,则可能会出现问题,但是这似乎可以降低CPU使用率,这似乎是一个问题。在SQL Server上运行,因为它仅在使用IEnumerable对象时返回数据。这也降低了客户端上的内存使用量,因为客户端仅在工作时加载MyType的一个实例,而不是加载所有出现的MyType(通过遍历整个DataReader并返回List或其他内容)。
  • 是否有任何实例可以让您想到不希望以这种方式使用IEnumerable的实例,或者您认为适合的任何实例?
  • 这会给SQL Server带来什么样的负载?
  • 这是您将在自己的代码中使用的东西吗(除非提及NHibernate,Subsonic等)?
  • --

    最佳答案

    我不会使用它,因为它隐藏了正在发生的事情,并且可能会留下数据库连接而没有适当的处置。

    当您读完最后一条记录时,连接对象将被关闭,并且如果您在该对象未处置之前停止阅读,则该连接对象将被关闭。例如,如果您知道一个结果中始终有十个记录,并且有一个循环从枚举器读取这十个记录,而没有进行第十一个Read调用,而该调用读取的是最后一项,则该连接未正确关闭。同样,如果您只想使用部分结果,则无法在不读取其余记录的情况下关闭连接。

    即使枚举器的内置扩展名也可能导致此问题,即使您正确使用它们也是如此:

    foreach (MyType item in GetMyTypeObjects().Take(10)) {
       ...
    }
    

    10-07 19:00
    查看更多