Обратите внимание, что удаление SqlDataReader, созданного с помощью SqlCommand.ExecuteReader (), не закроет / удалит базовое соединение.
Есть два общих шаблона. В первом читатель открывается и закрывается в пределах объема подключения:
using(SqlConnection connection = ...)
{
connection.Open();
...
using(SqlCommand command = ...)
{
using(SqlDataReader reader = command.ExecuteReader())
{
... do your stuff ...
} // reader is closed/disposed here
} // command is closed/disposed here
} // connection is closed/disposed here
Иногда удобно иметь метод доступа к данным, открыть соединение и вернуть читателя. В этом случае важно, чтобы возвращаемый считыватель был открыт с помощью CommandBehavior.CloseConnection, чтобы закрытие / удаление считывателя закрыло основное соединение. Шаблон выглядит примерно так:
public SqlDataReader ExecuteReader(string commandText)
{
SqlConnection connection = new SqlConnection(...);
try
{
connection.Open();
using(SqlCommand command = new SqlCommand(commandText, connection))
{
return command.ExecuteReader(CommandBehavior.CloseConnection);
}
}
catch
{
// Close connection before rethrowing
connection.Close();
throw;
}
}
и вызывающему коду просто нужно расположить читателя таким образом:
using(SqlDataReader reader = ExecuteReader(...))
{
... do your stuff ...
} // reader and connection are closed here.