«Недопустимая попытка вызвать Read, когда читатель закрыт» при использовании SqlDataReader - PullRequest
4 голосов
/ 24 января 2012

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) Я попытался mySettings.myCandidateList.Read () в (3) выше и снова получено одно и то же сообщение об ошибке.

6) Как я могу снова открыть SqlDataReader drCandidate для чтения данных?

7) Буду очень признателен за совет и помощь, пожалуйста.

Ответы [ 5 ]

6 голосов
/ 24 января 2012

Вы не можете прочитать считыватель, когда соединение closed или disposed.Если вы хотите использовать эти строки (получить результат) позже в своем коде, вам нужно создать List или DataTable.

Например,

System.Data.DataTable dt = new System.Data.DataTable();
dt.Load(drAvailableCandidate);
1 голос
/ 24 января 2012

Если вы хотите использовать устройство чтения данных на более позднем этапе, вы должны указать то же самое в качестве параметра для метода 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();  
}
0 голосов
/ 07 ноября 2015

Просто добавьте к уже полученным ответам, если вы используете async / await, тогда легко разобраться с этим, не ожидая операции внутри блока using в SqlConnection.Например, выполнение следующих действий может привести к сообщенной ошибке

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

Проблема здесь в том, что мы не ожидаем операции внутри использования, поэтому она удаляется до того, как мы фактически выполним асинхронную операцию подчиненного объекта.Довольно очевидно, но поймал меня раньше.

Правильнее всего подождать внутри использования.

public async Task GetData()
{
    using(new SqlConnection(connString))
    {
        await SomeAsyncOperation();
    }
}
0 голосов
/ 24 января 2012

Когда вы вызываете Close для объекта SqlConnection (sqlConn.Close();), он закрывает соединение и ваше устройство чтения данных.Вот почему вы получаете сообщение об ошибке, когда пытаетесь прочитать данные из SqlDataReader из формы B.

Вам нужно изменить определение свойства myCandidateList, чтобы вместо этого возвращать представление данныхчто вы извлекли из вашего drAvailableCandidate читателя.

По сути, вам нужно перебирать строки в объекте drAvailableCandidate, извлекать значения и кэшировать их в свойстве для последующего извлечения.

0 голосов
/ 24 января 2012

Вы закрываете соединение, прежде чем пытаетесь читать с ридера.Это не сработает.

...