SqlConnection.Close() внутри оператора using

Все ваши ответы были полезны. Спасибо всем, кто приложил усилия, чтобы ответить на мой вопрос. Приветствия:)

Я использую этот код:

    public void InsertMember(Member member)
    {
        string INSERT = "INSERT INTO Members (Name, Surname, EntryDate) VALUES (@Name, @Surname, @EntryDate)";

        using (sqlConnection = new SqlConnection(sqlConnectionString_WORK))
        {
            sqlConnection.Open();

            using (SqlCommand sqlCommand = new SqlCommand(INSERT, sqlConnection))
            {
                sqlCommand.Parameters.Add("@Name", SqlDbType.VarChar).Value = member.Name;
                sqlCommand.Parameters.Add("@Surname", SqlDbType.VarChar).Value = member.Surname;
                sqlCommand.Parameters.Add("@EntryDate", SqlDbType.Date).Value = member.EntryDate;

                sqlCommand.ExecuteNonQuery();
            }
        }
    }

Это неправильно, если я не добавляю sqlConnection.Close();, прежде чем удалять его? Я имею в виду... Он не показывает никаких ошибок, никаких проблем вообще... Лучше ли сначала закрыть его? Если да, то почему?

Ответы

Ответ 1

Не нужно Close or Dispose блок using позаботится об этом для вас.

Как указано в MSDN:

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

private static void OpenSqlConnection(string connectionString) 
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();
        Console.WriteLine("ServerVersion: {0}", connection.ServerVersion);
        Console.WriteLine("State: {0}", connection.State);
    } 
}

Ответ 2

using statement ensures that Dispose is called, даже если исключение возникает, когда вы вызываете методы на объекте. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; на самом деле, вот как оператор using переводится компилятором. MSDN

Итак, в конечном итоге ваша строка кода

  using (sqlConnection = new SqlConnection(sqlConnectionString_WORK))

будет преобразован в обычный try finally block путем вызова компилятора IDisposable object in the finally

Ответ 3

Оператор using - это блок finally try, и в вашем случае последний блок будет иметь вызов connection.Dispose(). Таким образом, вам действительно не нужен независимый оператор connection.Close().

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

try
{
sqlConnection.Open();
// ....
}
finally
{
if(sqlConnection != null)
      sqlConnection.Dispose();
}

Ответ 4

Нет, это не так. SqlConnection закроет соединение после того, как он пройдет с помощью блока и вызовет метод Dispose. SqlConnection.Dispose(), равный методу SqlConnection.Close().

Из MSDN: Если SqlConnection выходит из области действия, он не будет закрыт. Поэтому вы должны явно закрыть соединение, вызвав Close или Dispose. Close и Dispose являются функционально эквивалентными.

Ответ 5

Вы используете Using, который будет Dispose() для вас.

Если вы используете соединение вне инструкции Using, тогда да - вам нужно закрыть соединение по завершении.

Ответ 6

В соответствии с документацией MSDN для метода Close:

вы должны явно закрыть соединение, вызвав Закрыть или Dispose. Закрыть и Dispose являются функционально эквивалентными.

Поэтому вызов Dispose (неявно, даже, используя using) будет как бы закрывать ваши базы.

Стоит также отметить, что я считаю, хотя и не конкретным для вашего случая, что Close всегда будет эффективно вызываться, когда вещь обернута в оператор using, что может быть не так, если оно должно быть опущено и исключение происходит без правильной обработки try/catch/finally.

Ответ 7

Неправильно, если я не добавляю sqlConnection.Close(); перед удалением его

Нет, это не так, пока вы используете свое соединение в Using. Когда вы выйдете из области использования, Dispose вызывается для соединения sql. который закроет существующее соединение и освободит все ресурсы.

Ответ 8

Это очень интересный вопрос и не столь очевидный, как многие думают. Использование оператора будет корректно работать для соединения только в том случае, если будут удалены все объекты, которые используют соединение. Некоторое время назад у нас возникла проблема с открытыми соединениями на нашем сервере sql. Все выглядело отлично, потому что соединения находились внутри с помощью операторов, но один из разработчиков создал несколько методов с SqlDataReader и не закрыл его правильно. Из-за этого соединения не были выпущены.

Причиной этого является то, как работает сборщик мусора. Короче говоря - он создает карту объектов для размещения и фактически распоряжается ими, когда нет активных ссылок на эти объекты.