我有 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.
}
}
消息很明显:您不能在DataReader
仍处于打开状态时同时对不同的SqlCommand
实例使用相同的连接。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
的代码的任何部分。