¿Se requiere SqlCommand.Dispose () si se eliminará SqlConnection asociado?

Usualmente uso un código como este:

using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString)) { var command = connection.CreateCommand(); command.CommandText = "..."; connection.Open(); command.ExecuteNonQuery(); } 

¿Mi command se eliminará automáticamente? ¿O no y tengo que envolverlo using block? ¿Es necesario disponer de SqlCommand ?

Solo haz esto:

 using(var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyConn"].ConnectionString)) using(var command = connection.CreateCommand()) { command.CommandText = "..."; connection.Open(); command.ExecuteNonQuery(); } 

No llamar a disponer en el comando no hará nada malo. Sin embargo, si se llama a Dispose, se suprimirá la llamada al finalizador , por lo que las llamadas eliminan una mejora del rendimiento.

La política más segura es llamar siempre a Dispose() sobre un objeto si implementa IDisposable , ya sea explícitamente o mediante un bloque que lo use. Puede haber casos en que no sea necesario, pero llamarlo de todos modos nunca debe causar problemas (si la clase está escrita correctamente). Además, nunca se sabe cuándo puede cambiar una implementación, lo que significa que cuando la llamada no era necesaria anteriormente, ahora es definitivamente necesario.

En el ejemplo que ha dado, puede agregar un bloque de uso interno adicional para el comando, así como también mantener el bloque de uso externo para la conexión.

Sí, debería, incluso si la implementación actualmente no está haciendo mucho, no sabe cómo se va a cambiar en el futuro (por ejemplo, versiones de framework más recientes). En general, debe disponer de todos los objetos que implementen IDisposable para estar en el lado seguro.

Sin embargo, si la operación se aplaza y no se controla el scope completo (por ejemplo, cuando se trabaja de forma CloseConnection o cuando se devuelve un SqlDataReader ), puede establecer CommandBehavior en CloseConnection para que tan pronto como el lector CloseConnection , el la conexión está correctamente cerrada / desechada para usted.

En la práctica, puedes saltear Dispose . No libera ningún recurso. Ni siquiera suprime la finalización ya que el constructor hace eso.

En teoría, Microsoft podría cambiar la implementación para tomar un recurso no administrado, pero espero que salgan con una API que elimine la clase base del Component mucho antes de que lo hagan.

Puedes descubrir este tipo de cosas usando Reflector .

Hice una pequeña excavación (sugiero que también excaves para estar completamente seguro del rest de esto, ya que no lo intenté tan duro) y parece que cuando matas una conexión no hay eliminación de ningún niño asociado. con esa conexión. Además, en realidad no parece que la eliminación de un comando en realidad hace tanto. Establecerá un campo en nulo, se separará de un contenedor (esto puede evitar una fuga de memoria administrada) y generará un evento (esto podría ser importante, pero no puedo ver quién está escuchando este evento).

De cualquier manera, es una buena práctica usar estas cosas en un bloque de uso o para asegurarse de disponer de él utilizando un patrón de disposición en el objeto que contiene la conexión (si tiene la intención de mantener el comando por un tiempo).