SqlCommand.Dispose fecha a conexão?
-
09-06-2019 - |
Pergunta
Posso usar essa abordagem de forma eficiente?
using(SqlCommand cmd = new SqlCommand("GetSomething", new SqlConnection(Config.ConnectionString))
{
cmd.Connection.Open();
// set up parameters and CommandType to StoredProcedure etc. etc.
cmd.ExecuteNonQuery();
}
Minha preocupação é :O método Dispose do SqlCommand (que é chamado ao sair do bloco using) fechará o objeto SqlConnection subjacente ou não?
Solução
Não, descartando o SqlCommand
não afetará a conexão.Uma abordagem melhor seria também envolver o SqlConnection
em um bloco using também:
using (SqlConnection conn = new SqlConnection(connstring))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand(cmdstring, conn))
{
cmd.ExecuteNonQuery();
}
}
Caso contrário, a Conexão permanece inalterada pelo fato de um Comando que a estava utilizando ter sido descartado (talvez seja isso que você deseja?).Mas lembre -se de que uma conexão também deve ser descartada e provavelmente mais importante para descartar do que um comando.
EDITAR:
Acabei de testar isso:
SqlConnection conn = new SqlConnection(connstring);
conn.Open();
using (SqlCommand cmd = new SqlCommand("select field from table where fieldid = 1", conn))
{
Console.WriteLine(cmd.ExecuteScalar().ToString());
}
using (SqlCommand cmd = new SqlCommand("select field from table where fieldid = 2", conn))
{
Console.WriteLine(cmd.ExecuteScalar().ToString());
}
conn.Dispose();
O primeiro comando foi descartado quando o bloco using foi encerrado.A conexão ainda estava aberta e boa para o segundo comando.
Portanto, descartar o comando definitivamente não descarta a conexão que ele estava usando.
Outras dicas
SqlCommand.Dispose não será suficiente porque muitos SqlCommand(s) podem (re)usar o mesmo SqlConnection.Centralize seu foco no SqlConnection.
Eu uso esse padrão.Eu tenho esse método privado em algum lugar do meu aplicativo:
private void DisposeCommand(SqlCommand cmd)
{
try
{
if (cmd != null)
{
if (cmd.Connection != null)
{
cmd.Connection.Close();
cmd.Connection.Dispose();
}
cmd.Dispose();
}
}
catch { } //don't blow up
}
Então eu sempre crio comandos SQL e conexões em um bloco try (mas sem ser envolvido em um bloco using) e sempre tenho um bloco final como:
finally
{
DisposeCommand(cmd);
}
O objeto de conexão sendo uma propriedade do objeto de comando torna o bloco using estranho nessa situação - mas esse padrão faz o trabalho sem sobrecarregar seu código.