“使用SqlDataReader时,无法尝试在读取器关闭时调用Read”

时间:2012-01-24 02:34:21

标签: c# 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)然后我收到错误“当阅读器关闭时,Invalide尝试调用Read。”

5)我在上面的(3)中尝试了mySettings.myCandidateList.Read()并再次收到相同的错误消息。

6)如何重新打开SqlDataReader drCandidate来读取数据?

7)非常感谢您的建议和帮助。

5 个答案:

答案 0 :(得分:6)

连接为closeddisposed后,您无法读取阅读器。如果您希望稍后在代码中使用这些行(获取结果),则需要创建ListDataTable

例如,

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

答案 1 :(得分:1)

如果要在以后阶段使用datareader,则必须将相同的参数指定为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(); 

确保在使用datareader后将其丢弃,因为与数据库的连接将保持打开状态,直到datareader关闭为止。最好在FormB中更改您的代码,如下所示。

using (mySettings.myCandidateList)
{
mySettings.myCandidateList.Read();  
}

答案 2 :(得分:0)

在尝试从阅读器中读取之前,您正在关闭连接。那不行。

答案 3 :(得分:0)

当您在SqlConnection对象(sqlConn.Close();)上调用“关闭”时,它会关闭连接和数据阅读器。这就是当您尝试从FormB中读取SqlDataReader时收到错误的原因。

您需要做的是更改myCandidateList属性的定义,而不是返回您从drAvailableCandidate阅读器中提取的数据的表示形式。

基本上你需要做的是遍历drAvailableCandidate对象中的行,提取值并将它们缓存在你的属性中以便以后检索。

答案 4 :(得分:0)

只是为了添加已经给出的答案,如果你正在使用async / await,那么很容易因为没有等待SqlConnection的using块内的操作而被捕获。例如,执行以下操作可以提供报告的错误

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

这里的问题是我们没有等待使用中的操作,因此它在我们实际执行underling异步操作之前被处理掉了。相当明显,但之前已经把我抓了出来。

在使用中等待内容是正确的。

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