2013-05-03 3 views
3

Если я создаю экземпляр SqlDataReader внутри блока using, мне нужно позвонить close() на читателя?Если SqlDataReader будет удален, мне нужно вызвать функцию close()?

Простой пример поиска пользователя, показанного ниже.

using (var connection = new SqlConnection(Settings.GetValue("SqlConnection"))) 
    { 
    SqlCommand command = new SqlCommand("select * from Users where Id = @Id", connection);   
    command.Parameters.Add("@Id", SqlDbType.UniqueIdentifier); 
    command.Parameters["@Id"].Value = id; 

    using (SqlDataReader reader = command.ExecuteReaderWithRetry()) 
    { 
     reader.Read(); 

     if (reader.HasRows) 
     { 
     //Do work 
     } 

     //Is this neccesary? 
     reader.Close(); 
    } 
    } 
+2

Вы найдете ответы на похожие топы на SO. – JeffO

+2

Сторона примечания: 'SqlCommand' также реализует' IDisposable'. – JosephHirn

+0

@JeffO Dang it, я думал, что SO скажет мне, что этот вопрос не принадлежит. – Justin

ответ

12

Если он используется в блоке, то он автоматически закрывается. Вам не нужно явно закрывать его.

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

Ваш неустановленный SqlCommand на самом деле является хорошим примером того, почему эмуляция C# для RAII не является «реальной» RAII. Вы должны принять явное действие (создание блоков) для RAII, чтобы выполнить удар, что эквивалентно явному закрытию, хотя и с другим синтаксисом.

+0

Благодарим вас за информацию о бонусе о SqlCommand. – Justin

+2

Вы также можете посмотреть на него по-другому: если вы не используете 'using', это как если бы вы использовали' new' в C++. – svick

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