Observe que descartar um SqlDataReader instanciado usando SqlCommand.ExecuteReader () não fechará / descartará a conexão subjacente.
Existem dois padrões comuns. Na primeira, o leitor é aberto e fechado no âmbito da conexão:
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
Às vezes, é conveniente ter um método de acesso a dados para abrir uma conexão e retornar um leitor. Nesse caso, é importante que o leitor retornado seja aberto usando CommandBehavior.CloseConnection, para que fechar / descartar o leitor feche a conexão subjacente. O padrão é mais ou menos assim:
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;
}
}
e o código de chamada precisa apenas dispor o leitor assim:
using(SqlDataReader reader = ExecuteReader(...))
{
... do your stuff ...
} // reader and connection are closed here.