Está fechando / descartando um SqlDataReader necessário se você já está fechando o SqlConnection?

Eu notei essa pergunta , mas minha pergunta é um pouco mais específica.

Existe alguma vantagem em usar

using (SqlConnection conn = new SqlConnection(conStr)) { using (SqlCommand command = new SqlCommand()) { // dostuff } } 

ao invés de

 using (SqlConnection conn = new SqlConnection(conStr)) { SqlCommand command = new SqlCommand(); // dostuff } 

Obviamente, importa se você planeja executar mais de um comando com a mesma conexão, já que fechar um SqlDataReader é mais eficiente do que fechar e reabrir uma conexão (chamar conn.Close();conn.Open(); também conn.Close();conn.Open(); o conexão).

Eu vejo muitas pessoas insistindo que a falha em fechar o SqlDataReader significa deixar resources de conexão aberta, mas isso não se aplica apenas se você não fechar a conexão?

Na minha opinião, existem duas regras a seguir aqui:

  1. As classs que implementam IDisposable devem ser agrupadas em um bloco de using .
  2. Você não deve confiar na implementação de IDisposable de uma class para ignorar a regra 1.

Ou seja, mesmo se você souber que a disposição do object de conexão resolveu descartar seu object de comando associado, você não deve confiar nesse comportamento.

By the way, é possível aninhar usando blocos de uma forma mais limpa:

 using (SqlConnection conn = new SqlConnection(conStr)) using (SqlCommand command = new SqlCommand()) { // dostuff } 

e eu usaria

 SqlCommand command = conn.CreateCommand(); 

em vez de criar um novo SqlCommand e associá-lo à conexão.

Tecnicamente não é necessário; fechar um SqlConnection deve destruir todos os resources que o SqlDataReader está usando. O contrário também é verdade; você não precisa Dispose o SqlConnection se você descartar um SqlDataReader que foi criado com CommandBehavior.CloseConnection .

Na prática , porém, quando uma class implementa IDisposable , você deve Dispose la quando terminar de usá-la. Os detalhes de implementação das classs da estrutura estão sujeitos a alterações a qualquer momento e, a menos que a documentação descreva especificamente as circunstâncias sob as quais não é necessário Dispose a instância, há sempre a possibilidade de alguma alteração / atualização futura resultar no código ter uma vazamento de resources.

Não é realmente um esforço extra – então apenas envolva-o em um bloco de using .

Pode não ser necessário em muitos casos, mas é a melhor prática por um motivo. Não há razão para deixar os resources persistirem além do ponto em que eles não são mais úteis. A construção using ajuda a garantir isso.

Não é apenas uma questão de você liberar o recurso agora contra a garbage collection liberando-o mais tarde?

Há uma diferença. Se você criar 2 desses leitores sem abrir / fechar a conexão, mas não descartar o primeiro antes de usar o segundo, você terá um conflito dizendo que a conexão já está associada a um leitor aberto.