我已经收到用户的报告,他们在使用我的应用程序时遇到此异常:
ExecuteReader requires an open and available Connection. The connection's current state is open.
| System.InvalidOperationException
| at System.Data.SqlClient.SqlConnection.GetOpenConnection(String method)
| at System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command)
| at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async)
| at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
| at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
| at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
| at System.Data.SqlClient.SqlCommand.ExecuteReader()
| at MyProject.Database.GetData(DataType data, SqlConnection& _conn)
但是,我似乎无法重现此异常,实际上我什至不知道其含义:即,如果连接的当前状态为打开状态,那么问题出在哪里?为什么例外?
我尝试逐步浏览代码,并保持连接状态为打开状态,但它只能正确读取数据。确实,Microsoft Docs似乎暗示如果关闭连接会发生这种情况,但是正如您从异常消息中看到的那样,它是打开的。
以下是相关代码:
private int GetData(DataType data, ref SqlConnection _conn)
{
string sqlStr = string.Format("select top 1 * from dbo.DataTable where [Id] = N'{0}'", data.Id);
using (SqlCommand cmd = new SqlCommand(sqlStr, _conn))
{
SqlDataReader rs = null;
try
{
if (_trans != null) cmd.Transaction = _trans;
rs = cmd.ExecuteReader();
if (rs == null)
return DB_ERROR;
int attI = rs.GetOrdinal("FileData");
int fileNameI = rs.GetOrdinal("FileName");
while (rs.Read())
{
dataFile.FileData = (byte[]) rs.GetValue(attI);
dataFile.FileName = DBCommon.ColStr(rs, fileNameI);
}
rs.Close();
rs = null;
return DB_OK;
}
catch (Exception e)
{
LogException(e);
return DB_ERROR;
}
finally
{
if (rs != null)
rs.Close();
rs = null;
}
}
}
在调试时,我检查了_conn.State
属性,检查它是否为Open
,然后逐步执行rs = cmd.ExecuteReader();
行,但是它运行正常。
应注意,这是一个非常大的应用程序,具有许多表,每个表都具有与上述表相似的方法,它们均引用该_conn
对象。进行重组是不可行的。
其他任何问题都有关于如何预防的答案,但我正在尝试重现它,并了解其确切原因。