“阅读器关闭时调用 Read 的尝试无效”使用 SqlDataReader 时
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.myCandidateList.Read(),并再次收到相同的错误消息。
6)如何重新打开SqlDataReader drCandidate来读取数据?
7) 非常感谢您的建议和帮助。
1) I have the following codes:
private static sqlDataReader gCandidateList = null;
public SqlDataReader myCandidateList
{
set
{
gCandidateList = value;
}
get
{
return gCandidateList;
}
}
2) In FormA I have:
sqlConn.ConnectionString = mySettings.myConnString;
sqlConn.Open();
SqlCommand cmdAvailableCandidate = new SqlCommand(tempString, sqlConn);
SqlDataReader drAvailableCandidate = cmdAvailableCandidate.ExecuteReader();
mySettings.myCandidateList = drAvailableCandidate;
sqlConn.Close();
3) In FormB I want to reuse the data saved in myCandidatList so I use:
SqlDataReader drCandidate = mySettings.myCandidateList;
drCandidate.Read();
4) I then got the error "Invalide attempt to call Read when reader is closed."
5) I tried mySettings.myCandidateList.Read() in (3) above and again received the same error message.
6) How can I re-open SqlDataReader drCandidate to read data?
7) Would appreciate very much for advise and help, please.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
连接
关闭
或处置
后,您将无法读取阅读器。如果您想稍后在代码中使用这些行(获取结果),您需要创建一个List
或DataTable
。例如,
You can't read reader once the connection is
closed
ordisposed
. If you want to use those rows (fetch result) later in your code you need to create aList
orDataTable
.For instance,
如果您想在稍后阶段使用数据读取器,则必须将相同的参数指定为 ExecuteReader 方法。您在 FormA 中的代码应更改如下。
确保在使用数据读取器后将其丢弃,因为与数据库的连接将保持打开状态,直到数据读取器关闭。最好更改 FormB 中的代码,如下所示。
If you want to use the datareader at later stage, you have to specify the same as a parameter to the ExecuteReader Method. Your code in FormA should be changed as below.
Make sure to dispose the datareader once it is used, as the connection to the database will be held open till the datareader is closed. Better change your code in FormB as below.
在尝试从阅读器读取数据之前,您将关闭连接。那是行不通的。
You're closing the connection before you attempt to read from the reader. That won't work.
当您对
SqlConnection
对象调用 Close (sqlConn.Close();
) 时,它会关闭连接和数据读取器。这就是当您尝试从 FormB 中读取SqlDataReader
时收到错误的原因。您需要做的是更改
myCandidateList
属性的定义,以返回从drAvailableCandidate
阅读器中提取的数据的表示形式。本质上,您需要做的是迭代
drAvailableCandidate
对象中的行,提取值并将它们缓存在您的属性中以供以后检索。When you call Close on the
SqlConnection
object (sqlConn.Close();
) it closes the connection and your data reader. That is why you are getting the error when you try to read from yourSqlDataReader
from FormB.What you need to do is change the definition of your
myCandidateList
property to instead return a representation of the data that you have extracted from the yourdrAvailableCandidate
reader.Essentially what you need to do is iterate through the rows in the
drAvailableCandidate
object, extract the values and cache them in your property for later retrieval.只是为了添加已经给出的答案,如果您使用 async/await 那么很容易因为不等待 SqlConnection 的 using 块内的操作而陷入困境。例如,执行以下操作可能会给出报告的错误。
这里的问题是我们没有等待 using 中的操作,因此在我们实际执行底层异步操作之前它已被处理掉。相当明显,但之前已经让我发现了。
正确的做法是在使用中等待。
Just to add to the answers already given, if you're using async/await then it's easy to get caught out with this by not awaiting an operation inside a using block of a SqlConnection. For example, doing the following can give the reported error
The problem here is we're not awaiting the operation inside the using, therefore it's being disposed of before we actually execute the underling async operation. Fairly obvious, but has caught me out before.
The correct thing to do being to await inside the using.