C# 已经有一个与此命令关联的打开的 DataReader 必须先关闭

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9023452/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 05:38:42  来源:igfitidea点击:

There is already an open DataReader associated with this Command which must be closed first

c#datareader

提问by Marcus3329

This is the code I have.

这是我的代码。

/// <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;
}

采纳答案by Icarus

Your problem is that you apparently have one instance of m_ConStr; if the method is called concurrently only one of them will be able to use the connection and the other one will fail with the exception you are receiving.

你的问题是你显然有一个m_ConStr; 如果同时调用该方法,则只有其中一个可以使用该连接,而另一个将失败并出现您收到的异常。

Use this pattern instead:

请改用此模式:

using (SqlConnection conn  = new SqlConnection())
{
    conn.Open();
    Sqlmd.Connection = conn;
    SqlDataAdapter da = new SqlDataAdapter(Sqlmd);
   //...etc
}

In other words, don't define connection as a global variable to the class.

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

回答by RQDQ

You're trying to run multiple actice result sets (aka MARS).

您正在尝试运行多个动作结果集(又名MARS)。

Two possible solutions come to mind:

想到了两种可能的解决方案:

  1. Open open a new connection in your GetContractResultSetByLead
  2. Enable MARS on your database server (described in the above link).
  1. 在 GetContractResultSetByLead 中打开一个新连接
  2. 在您的数据库服务器上启用 MARS(在上面的链接中描述)。

回答by Ravi Gadag

i suggest You can using block to ensure proper disposing of sqlconnection.

我建议您可以使用块来确保正确处理 sqlconnection。

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

the other way is you can also set MARS property in your connection, if you needed.

另一种方法是,如果需要,您还可以在连接中设置 MARS 属性。

SqlConnection m_ConStr;= new SqlConnection("Server= serverName;Database=yourDatabase;
        MultipleActiveResultSets=true;");

回答by Marc Gravell

All of your short-lived IDisposable objects there are lacking a "using". By extension, then, it is possible that you've done something like:

你所有短命的 IDisposable 对象都缺乏“使用”。推而广之,您可能已经完成了以下操作:

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

But this does not dispose / close the reader. If this is the case, add "using":

但这不会配置/关闭阅读器。如果是这种情况,请添加“使用”:

using(var reader = anotherCommand.ExecuteReader()) {
    ...
}

Which closes the reader, regardless of how we exit. Commands, connections, readers and transactions are all disposable and should all usually use "using".

无论我们如何退出,这都会关闭阅读器。命令、连接、读取器和事务都是一次性的,通常都应该使用“使用”。