2013-09-03 3 views
15

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

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

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(); перед утилизацией его? Я имею в виду ... Это не показывает никаких ошибок, никаких проблем вообще ... Лучше ли сначала закрыть его? Если да, то почему?

+2

В, используя оператор будет 'Dispose' соединение даже в случае исключения, так что вы не «Мне действительно нужен вызов« Закрыть » – V4Vendetta

ответ

21

Нет необходимости Close or Disposeusing блок позаботится об этом за вас.

Как указано из 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); 
    } 
} 
+0

Речь идет о' Close() ', а не' Dispose() ':) – Matten

+0

@Matten - спасибо - только что отредактирован. –

+1

OK, если код имеет соединение. Close(); как раз перед вашей второй последней фигурной скобкой '}'? Это вызовет исключение, когда используемый блок попытается закрыть соединение, которое уже закрыто кодом? – variable

1

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

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

1

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

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

1

По MSDN documentation for the Close method:

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

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

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

+0

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

+0

@ DarrenDavies Точно. Это более подробно описано в деталях. –

1

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

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

2

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

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

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

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

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

3

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

Смежные вопросы