Можно ли вводить DbCommand перед итерацией DbDataReader

#c# #ado.net #dispose #dbdatareader

#c# #ado.net #утилизировать #dbdatareader

Вопрос:

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

 public static DbDataReader ExecuteQuery(DbConnection connection,string sql)
{
   DbCommand command = connection.CreateCommand();
   command.CommandText = sql;

   using(command)
   {
      return command.ExecuteReader();    
   }
}
  

Вызывающий код закрывает соединение и соответствующим образом удаляет считыватель и соединение.

Мой вопрос — можно ли / правильно ли вводить экземпляр command (как это делается с помощью блока using) перед итерацией reader? Я не ожидаю, что какие-либо параметры OUT будут заполнены после закрытия программы чтения. Выполняет ли ADO.NET У API есть какие-либо строгие рекомендации относительно этого?

Ответ №1:

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

Команды — это средство выполнения инструкций для соединения, но не содержат никаких данных, вот почему это работает. Пока соединение открыто, вы можете использовать свой reader.

PS. существует также хорошая перегрузка ExecuteReader, которая инструктирует читателя закрыть соединение непосредственно для вас при удалении, полезно, когда соединение создается локально, как вы делаете с помощью команды, а не передается извне.

Комментарии:

1. Хотя это звучит немного как метод проб и ошибок, можете ли вы гарантировать, что читатели из всех ADO.NET реализации игнорируют состояние команды? Технически возможно сделать его зависимым, поскольку команда является единственным объектом, способным создать средство чтения.

2. @Davide — ya Я знаю, что «использование» — это удаление команды и, следовательно, вопрос. Проблема в том, что код, похоже, работает для определенных драйверов, но не для всех!

3. Нет, это не попытка ошибочный подход — это способ, которым выполняется так много слоев данных. В основном объект command создается и в любом случае используется или не используется в методе, а reader доступен и может использоваться снаружи. Если бы это не сработало, там было бы так много сломанных DAL!

4. фактически, команда содержит значения параметров; и out / return значения параметров обновляются только в конце потока TDS, т. Е. Когда считыватель доходит до конца. Таким образом, технически читатель действительно возвращается к состоянию команды. Тем не менее, я подозреваю, что это будет работать нормально в любом случае.

5. Marc если вы хотите прочитать параметр out, вы наверняка все еще находитесь в методе, и command все еще там, поскольку вы не сможете получить к нему доступ из вызывающего метода, если вы только получили reader.