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
There is already an open DataReader associated with this Command which must be closed first
提问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:
想到了两种可能的解决方案:
- Open open a new connection in your GetContractResultSetByLead
- Enable MARS on your database server (described in the above link).
- 在 GetContractResultSetByLead 中打开一个新连接
- 在您的数据库服务器上启用 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".
无论我们如何退出,这都会关闭阅读器。命令、连接、读取器和事务都是一次性的,通常都应该使用“使用”。

