Как я могу закрыть мои соединения после того, как звонящий заканчивает с ними? - PullRequest
4 голосов
/ 16 марта 2012

Я создал следующий метод:

 public System.Data.OleDb.OleDbDataReader GetReader(string sqlQuery)
  {

          System.Data.OleDb.OleDbConnection myConnection = new System.Data.OleDb.OleDbConnection();
          LoadConnectionStrings();
          myConnection.ConnectionString = ConnectionString;
          myConnection.Open();
          System.Data.OleDb.OleDbCommand myCommand = new System.Data.OleDb.OleDbCommand(sqlQuery, myConnection);
          System.Data.OleDb.OleDbDataReader myReader = null;
          myReader = myCommand.ExecuteReader();

          return myReader;

  }

Несколько тысяч строк кода полагаются на него, и я полагаю, что не особо задумывался, когда реализовал его ...

Во всяком случае ,.Если я получу считыватель таким способом, у меня не будет способа закрыть соединение, и если я закрою соединение до того, как считыватель вызовет метод read (), оно взорвется, когда перейдет к чтению, и скажет, что соединение с базой данных необходимобыть открытым.

Вопрос в том, как закрыть соединение с предыдущими телами кода?Или вообще все соединения, может быть ..

Из того, что я прочитал здесь , если вы специально не вызываете 'close ()', оно не закрывается, и если вы 'Если вы используете файл доступа 2003, это как бы оставляет вас в мире боли

Ответы [ 4 ]

12 голосов
/ 16 марта 2012

В этом случае соединение должно оставаться открытым, чтобы считыватель работал, однако существует перегрузка для ExecuteReader, которая позволяет указать флаг для считывателя, чтобы закрыть соединение, когда считыватель закрыт:

myReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection);

Это позволяет вызывающему абоненту использовать:

using(var reader = GetReader(query)) {
    //...
}

И соединение будет чисто закрыто, когда вызывающий абонент выполнит считыватель.

1 голос
/ 16 марта 2012

Я использую сделать что-то вроде:

IDataReader GetReader(...)
{
    IDbConnection connection = ...;
    try
    {
        IDbCommand command = ...;
        command.Connection = connection;
        connection.Open();
        return command.ExecuteReader(CommandBehavior.CloseConnection);
    }
    catch
    {
        connection.Close();
        throw;
    }
}

Это не закрывает IDbCommand, но по моему опыту это нормально, пока соединение закрыто.

1 голос
/ 16 марта 2012

Я согласен с Марком, но хочу указать на недостаток в вашем подходе.

Этот механизм скрывает соединение от вызывающей стороны, поэтому вызывающая сторона не может использовать его для других операций с базой данных.Он также определяет связь со временем жизни считывателя, так что, если будут предприняты какие-либо другие действия, они должны произойти до утилизации считывателя.

Может быть, лучше, чтобы вызывающий абонент управляли просто передайте соединение в метод GetReader.

1 голос
/ 16 марта 2012

Не уверен, что это полностью решит вашу проблему, но вы можете использовать перегрузку IDBcommand.ExecuteReader (CommandBehavior) .

Если вы передадите CommandBehavior.CloseConnection, соединение с базой данных будет закрыто при закрытии вашего считывателя.

...