Повторное использование SqlConnection и SqlDataReader

Если я хочу запустить несколько запросов SELECT для разных таблиц, могу ли я использовать один и тот же SqlDataReader и SqlConnection для всех из них?? Будет ли разумным следующее?? (Я набрал это быстро, поэтому ему не хватает try / catch):

MySqlCommand myCommand = new MySqlCommand("SELECT * FROM table1", myConnection);

myConnection.Open();
SqlDataReader myDataReader = myCommand.ExecuteReader();

while(myReader.Read())
{
    //Perform work.
}

myCommand.commandText = "SELECT * FROM table2";

myReader = myCommand.ExecuteReader();

while(myReader.Read())
{
    //Perform more work
}

myReader.Close();
myConnection.Close();

Спасибо большое.

2 ответов


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

Что касается считывателя данных, вы фактически не повторно используете считыватель, каждый вызов ExecuteReader возвращает новый экземпляр нового считывателя, все, что вы повторно используете, это переменная, которая поддерживает ссылку на считыватель. Здесь лежит проблема, вы только явно закрываете последнего читателя и оставляете первого быть ГХ бы в некоторое более позднее время.

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

вы должны использовать try/finally блоки для обеспечения очистки ресурсов, Или вот быстрое изменение кода для использования using операторы для обеспечения очистки ресурсов, даже если есть исключение, которое предотвращает остальную часть кода от проведение.

using (var myConnection = GetTheConnection())
{
  myConnection.Open();

  var myCommand = new MySqlCommand("SELECT * FROM table1", myConnection))
  using (var myDataReader = myCommand.ExecuteReader())
  {
    while(myReader.Read())
    {
      //Perform work.
    }
  } // Reader will be Disposed/Closed here

  myCommand.commandText = "SELECT * FROM table2";
  using (var myReader = myCommand.ExecuteReader())
  {
    while(myReader.Read())
    {
      //Perform more work
    }
  } // Reader will be Disposed/Closed here
} // Connection will be Disposed/Closed here

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


Я обычно использую адаптеры, поэтому я ржавый на деталях читателя, но я думаю, что вы на правильном пути.

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