“阅读器关闭时调用 Read 的尝试无效”使用 SqlDataReader 时

发布于 2024-12-28 14:29:46 字数 922 浏览 0 评论 0原文

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

惟欲睡 2025-01-04 14:29:46

连接关闭处置后,您将无法读取阅读器。如果您想稍后在代码中使用这些行(获取结果),您需要创建一个 ListDataTable

例如,

System.Data.DataTable dt = new System.Data.DataTable();
dt.Load(drAvailableCandidate);

You can't read reader once the connection is closed or disposed. If you want to use those rows (fetch result) later in your code you need to create a List or DataTable.

For instance,

System.Data.DataTable dt = new System.Data.DataTable();
dt.Load(drAvailableCandidate);
说不完的你爱 2025-01-04 14:29:46

如果您想在稍后阶段使用数据读取器,则必须将相同的参数指定为 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();  
}

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.

sqlConn.ConnectionString = mySettings.myConnString;  
sqlConn.Open();  
SqlCommand cmdAvailableCandidate = new SqlCommand(tempString, sqlConn);  
SqlDataReader drAvailableCandidate = cmdAvailableCandidate.ExecuteReader(CommandBehavior.CloseConnection);  
mySettings.myCandidateList = drAvailableCandidate;  
sqlConn.Close(); 

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.

using (mySettings.myCandidateList)
{
mySettings.myCandidateList.Read();  
}
生死何惧 2025-01-04 14:29:46

在尝试从阅读器读取数据之前,您将关闭连接。那是行不通的。

You're closing the connection before you attempt to read from the reader. That won't work.

快乐很简单 2025-01-04 14:29:46

当您对 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 your SqlDataReader 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 your drAvailableCandidate 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.

感情洁癖 2025-01-04 14:29:46

只是为了添加已经给出的答案,如果您使用 async/await 那么很容易因为不等待 SqlConnection 的 using 块内的操作而陷入困境。例如,执行以下操作可能会给出报告的错误。

public Task GetData()
{
    using(new SqlConnection(connString))
    {
        return SomeAsyncOperation();
    }
}

这里的问题是我们没有等待 using 中的操作,因此在我们实际执行底层异步操作之前它已被处理掉。相当明显,但之前已经让我发现了。

正确的做法是在使用中等待。

public async Task GetData()
{
    using(new SqlConnection(connString))
    {
        await SomeAsyncOperation();
    }
}

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

public Task GetData()
{
    using(new SqlConnection(connString))
    {
        return SomeAsyncOperation();
    }
}

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.

public async Task GetData()
{
    using(new SqlConnection(connString))
    {
        await SomeAsyncOperation();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文