这个命令已经有一个关联的DataReader是打开状态,必须先关闭它。

8

这是我的代码。

/// <summary>
/// Method calls stored procedure and fills DataSet of contacts associated with Lead
/// </summary>
/// <param name="leadID">The ID associated with a Lead</param>
/// <returns>contacts list as DataSet</returns>
public static DataSet GetContactResultSetByLead(int leadID)
{
    SqlCommand Sqlmd = new SqlCommand("dbo.proc_contact");
    Sqlmd.CommandType = CommandType.StoredProcedure;
    Sqlmd.Parameters.Add("@LeadInfoID", SqlDbType.Int).Value = leadID;

    Sqlmd.Connection = m_ConStr;
    SqlDataAdapter da = new SqlDataAdapter(Sqlmd);

    DataSet data = new DataSet();
    try
    {
        da.Fill(data);
    }

    finally
    {
        m_ConStr.Close();
    }

    return data;
}

将此行代码 Sqlmd.Parameters.Add("@LeadInfoID", SqlDbType.Int).Value = leadID; 更改为 Sqlmd.Parameters.AddWithValue("@LeadInfoID", leadID); 如果您想保留 Global Connect,则请检查该连接的状态,如果打开则在使用之前关闭它。重构您的代码并使用有意义的变量名称....!将您的 Connection 包装在 using() {} 中。 - MethodMan
1
在da.Fill调用期间将执行Sqlmd。m_ConStr似乎是一个命名不当的变量 - 它似乎是指连接本身,而不是连接字符串。 - RQDQ
4个回答

9
你的问题在于你似乎只有一个 m_ConStr 实例;如果该方法被并发调用,只有一个实例能够使用连接,而另一个实例会因为接收到你所遇到的异常而失败。
请改用以下模式:
using (SqlConnection conn  = new SqlConnection())
{
    conn.Open();
    Sqlmd.Connection = conn;
    SqlDataAdapter da = new SqlDataAdapter(Sqlmd);
   //...etc
}

换句话说,不要将连接定义为类的全局变量。

不要将连接定义为全局变量:但是如何避免每次执行sp时都创建和打开连接。 在我的情况下,我必须执行很多sp,如果不实例化连接,则替代方法是每次创建和打开。有什么提示吗? - ff8mania

6

我建议您使用块来确保正确处置SqlConnection。

using (SqlConnection conn  = new SqlConnection())
{
    conn.Open();
    Sqlmd.Connection = conn;
    SqlDataAdapter da = new SqlDataAdapter(Sqlmd);
    Dataset ds = new Datasest
    da.Fill(ds)
}

另外一种方法是在连接中设置MARS属性(如果需要)。
SqlConnection m_ConStr;= new SqlConnection("Server= serverName;Database=yourDatabase;
        MultipleActiveResultSets=true;");

2
连接应该在本地声明(如果使用共享实例会发生各种副作用)。另外,为什么不使用using语句来管理连接的生命周期呢? - RQDQ

5

您所有的短期使用的IDisposable对象都缺少"using"。因此,可能您已经做了以下操作:

var reader = anotherCommand.ExecuteReader();
...

但这并没有解决/关闭读者的问题。如果是这种情况,请添加 "using":
using(var reader = anotherCommand.ExecuteReader()) {
    ...
}

无论我们如何退出,都会关闭读取器。命令、连接、读取器和事务均为一次性使用,通常应使用“using”语句。


1

您正在尝试运行多个活动结果集(也称为MARS)。

有两种可能的解决方案:

  1. 在GetContractResultSetByLead中打开一个新连接
  2. 在数据库服务器上启用MARS(在上面的链接中描述)。

你也可以尝试将以下内容添加到web.config文件的连接字符串中:connectionString="MultipleActiveResultSets=True;user=..." - Nestor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接