";当读取器关闭时调用Read的尝试无效”;使用SqlDataReader时
本文关键字:无效 SqlDataReader 使用 Read 调用 读取 quot | 更新日期: 2023-09-27 18:21:08
1)我有以下代码:
private static sqlDataReader gCandidateList = null;
public SqlDataReader myCandidateList
{
set
{
gCandidateList = value;
}
get
{
return gCandidateList;
}
}
2) 在FormA中,我有:
sqlConn.ConnectionString = mySettings.myConnString;
sqlConn.Open();
SqlCommand cmdAvailableCandidate = new SqlCommand(tempString, sqlConn);
SqlDataReader drAvailableCandidate = cmdAvailableCandidate.ExecuteReader();
mySettings.myCandidateList = drAvailableCandidate;
sqlConn.Close();
3) 在FormB中,我想重复使用保存在myCandidatList中的数据,所以我使用:
SqlDataReader drCandidate = mySettings.myCandidateList;
drCandidate.Read();
4) 然后我得到了错误"当阅读器关闭时,调用Read的尝试无效。"
5) 我尝试了上面(3)中的mySettings.myCCandidateList.Read(),但再次收到相同的错误消息。
6) 如何重新打开SqlDataReader drCandidate以读取数据?
7) 非常感谢您的建议和帮助。
一旦连接为closed
或disposed
,就无法读取读取器。如果稍后要在代码中使用这些行(获取结果),则需要创建一个List
或DataTable
。
例如,
System.Data.DataTable dt = new System.Data.DataTable();
dt.Load(drAvailableCandidate);
如果您想在稍后阶段使用数据读取器,您必须将其指定为ExecuteReader方法的参数。您在FormA中的代码应更改如下。
sqlConn.ConnectionString = mySettings.myConnString;
sqlConn.Open();
SqlCommand cmdAvailableCandidate = new SqlCommand(tempString, sqlConn);
SqlDataReader drAvailableCandidate = cmdAvailableCandidate.ExecuteReader(CommandBehavior.CloseConnection);
mySettings.myCandidateList = drAvailableCandidate;
sqlConn.Close();
请确保在使用数据读取器后对其进行处理,因为在关闭数据读取器之前,与数据库的连接将保持打开状态。最好更改FormB中的代码,如下所示。
using (mySettings.myCandidateList)
{
mySettings.myCandidateList.Read();
}
在尝试从读取器读取之前,您正在关闭连接。那行不通。
当您对SqlConnection
对象(sqlConn.Close();
)调用Close时,它会关闭连接和数据读取器。这就是为什么当您尝试从FormB读取SqlDataReader
时会出现错误。
您需要做的是更改myCandidateList
属性的定义,以返回从drAvailableCandidate
读取器中提取的数据的表示形式。
从本质上讲,您需要做的是遍历drAvailableCandidate
对象中的行,提取值并将其缓存在属性中以供以后检索。
只是为了增加已经给出的答案,如果您使用async/await,那么不等待SqlConnection的using块内的操作很容易陷入困境。例如,执行以下操作可以给出报告的错误
public Task GetData()
{
using(new SqlConnection(connString))
{
return SomeAsyncOperation();
}
}
这里的问题是,我们没有在using中等待操作,因此在实际执行underlines异步操作之前,它已经被处理掉了。很明显,但以前我也遇到过。
正确的做法是在使用中等待。
public async Task GetData()
{
using(new SqlConnection(connString))
{
await SomeAsyncOperation();
}
}