不允许嵌套SQLCommand?

时间:2017-08-07 04:35:50

标签: c# sqldatareader sqlcommand

我有2个SqlCommand,其中一个是嵌套的。为什么它不允许我发出第二个SqlCommand(我使用单独的SQLCommand)?它给出了错误"已经有一个与此命令关联的开放DataReader必须先关闭。" 。如果我使用单独的SqlConnection,那很好。

 SqlCommand cmd = new SqlCommand(qry, cn);

 SqlDataReader rd = cmd.ExecuteReader();

 while (rd.Read())
 {
      ....    
      try
      {
          SqlCommand cmd2 = new SqlCommand(qry2, cn);
          cmd2.ExecuteNonQuery();
      }
      catch (Exception e)
      {
          // I get this error here
          // System.Data; There is already an open DataReader associated with this Command which must be closed first.
      }        
 }

1 个答案:

答案 0 :(得分:1)

消息很明显:在SqlCommand仍处于打开状态时,您无法同时为不同的DataReader实例使用相同的连接。 SqlDataReader实例解释已经说过:

  

在使用SqlDataReader时,关联的SqlConnection是   忙于服务SqlDataReader,没有其他操作可以   在SqlConnection上执行而不是关闭它。情况就是这样   直到调用SqlDataReader的Close方法。例如,   在调用Close之前,您无法检索输出参数。

此问题的常见解决方案是在连接字符串上使用MultipleActiveResultSets=True

<add name="ConnectionName" connectionString="[connection string];MultipleActiveResultSets=True" ... />

然后,使用DataTable代替直接迭代DataReader

var dt = new DataTable();
dt.Load(rd);

foreach (DataRow row in dt.Rows)
{
    // other stuff

    try
    {
        SqlCommand cmd2 = new SqlCommand(qry2, cn);
        cmd2.ExecuteNonQuery();
    }
    catch (Exception e)
    {
        // throw exception
    }
}

此外,您可以使用SqlConnection.State属性轻松检查之前的连接是否仍处于打开状态(即提供DataReader):

// close if connection still open
if (cn.State == ConnectionState.Open)
{
    cn.Close();
}

// open if connection already closed
if (cn.State == ConnectionState.Closed)
{
    cn.Open();
}

上面的简单检查应该放在请求SqlConnection的代码的任何部分。