Нужно ли закрывать DbConnection, если используется предложение using?

Возможный дубликат:
Будет ли использование блокировать закрытие соединения с базой данных?

Является ли db.Close() ненужным в следующем?

using (DbConnection db = GetDbConnection())
{
   // do data-access stuff
   // ...

   db.Close();
}

person CJ7    schedule 20.08.2012    source источник
comment
нет, используя в реализации метода dispose в DBConnection, вызывает db.Close(). это не нужно   -  person Michal Franc    schedule 20.08.2012
comment
см. это отличное объяснение IDisposable: stackoverflow.com/a/538238/110933   -  person davek    schedule 20.08.2012


Ответы (5)


Нужно ли закрывать DbConnection, если используется предложение using?

Нет, нет необходимости закрывать DbConnection, если используется предложение использования?

и

Да, здесь это не нужно, потому что, когда область using заканчивается, соединение будет располагаться, что означает закрытие и освобождение всей памяти.

Поскольку DBConnection реализует интерфейс IDisposable, функция закрытия есть в методе Dispose DBConnection.

Но если некоторые строки находятся после закрытия строки, это полезно

using (DbConnection db = GetDbConnection())
{
  // do data-access stuff
  // ...

  db.Close(); //Useless
}

Но тут пригодится

using (DbConnection db = GetDbConnection())
{
  // do data-access stuff
  // ...

  db.Close(); //Useful

 // Some more code
}

В этом случае вы можете сделать

using (DbConnection db = GetDbConnection())
{
  // do data-access stuff
  // ...

}

// Some more code which was previously inside using section.
person Nikhil Agrawal    schedule 20.08.2012
comment
+1 за красивый дизайн, который можно закрыть вручную, если существует больше кода, который не использует соединение. Однако в этом случае лучше не включать этот код в блок использования. - person Myrtle; 20.08.2012
comment
@Aphelion: да, конечно, код ниже Close() не должен быть в блоке - person CJ7; 20.08.2012
comment
Почему полезен еще один код ниже db.CLose()? - person cuongle; 20.08.2012
comment
@CuongLe: может быть код, который работает со значениями, полученными после запуска некоторого запроса через это соединение. - person Nikhil Agrawal; 20.08.2012
comment
@NikhilAgrawal Хороший вопрос. В этом случае я бы рекомендовал хранить результаты вне области using. - person Myrtle; 20.08.2012
comment
В этом случае он выдаст исключение, потому что соединение действительно закрыто, но все еще запутано. - person cuongle; 20.08.2012
comment
@CuongLe: Что, если эти результаты будут получены до закрытия соединения. - person Nikhil Agrawal; 20.08.2012
comment
если эти результаты извлекаются до подключения, это не тот случай, когда больше кода ниже db.CLose() полезно. - person cuongle; 20.08.2012
comment
@CuongLe: здесь больше кода бесполезно. Если какой-то код находится после db.Close();, полезно закрыть его вручную. - person Nikhil Agrawal; 20.08.2012

Просто чтобы убедиться, что я проверил код :)

   protected override void Dispose(bool disposing)
    {
      if (disposing)
      {
        this._userConnectionOptions = (DbConnectionOptions) null;
        this._poolGroup = (DbConnectionPoolGroup) null;
        this.Close();
      }
      this.DisposeMe(disposing);
      base.Dispose(disposing);
    }

Это реализация SqlConnection, которая наследуется от DbConnection. Как видите, есть метод this.Close() :)

person Michal Franc    schedule 20.08.2012
comment
Мне вот тут интересно, оператор using вызывает Dispose() или Dispose(bool disposing) - person cuongle; 20.08.2012
comment
@Aphelion: пожалуйста, не могли бы вы также ответить на это? - person cuongle; 20.08.2012
comment
@CuongLe Он вызовет Dispose(), который является общедоступным. Затем его реализация вызовет Dispose(true). - person Myrtle; 20.08.2012

Насколько я знаю, когда вызывается метод Dispose(), автоматически выполняется Close().
Так что db.Close(); здесь не нужен.

person Marco    schedule 20.08.2012

В закрывающей фигурной скобке вызывается Dispose().

Я думаю, что в методе DbConnection метод Dispose также будет проверять, закрыто ли соединение. Так что нет, вероятно, в этом нет необходимости, но я лично считаю, что это хорошая практика, которая улучшает читаемость и не влияет на производительность, потому что Close будет вызываться так или иначе.

person Gerald Versluis    schedule 20.08.2012

Извлеченный код из реализации dispose класса SqlConnection (Производный от DbConnection):

public void Dispose()
{
   Dispose(true);
}

protected override void Dispose(bool disposing)
{
  if (disposing)
  {
     this.Close();
  }
  base.Dispose(disposing);
}

Ключевое слово using использует интерфейс IDisposable. Метод выше является реализацией метода. Это закроет соединение.

person Myrtle    schedule 20.08.2012