ejemplo datos crear conexiones conexion conectar con clase cerrar c# .net sql sqlconnection

datos - ejemplo conexion sql c#



¿Cuál es la forma correcta de garantizar que una conexión SQL se cierre cuando se lanza una excepción? (9)

Uso un patrón que se ve así como a menudo. Me pregunto si esto está bien o si hay una mejor práctica que no estoy aplicando aquí.

Específicamente me pregunto; en el caso de que se produzca una excepción, ¿el código que tengo en el bloque finally es suficiente para garantizar que la conexión se cierra adecuadamente?

public class SomeDataClass : IDisposable { private SqlConnection _conn; //constructors and methods private DoSomethingWithTheSqlConnection() { //some code excluded for brevity try { using (SqlCommand cmd = new SqlCommand(SqlQuery.CountSomething, _SqlConnection)) { _SqlConnection.Open(); countOfSomething = Convert.ToInt32(cmd.ExecuteScalar()); } } finally { //is this the best way? if (_SqlConnection.State == ConnectionState.Closed) _SqlConnection.Close(); } //some code excluded for brevity } public Dispose() { _conn.Dispose(); } }


¿Puedo sugerir esto?

class SqlOpener : IDisposable { SqlConnection _connection; public SqlOpener(SqlConnection connection) { _connection = connection; _connection.Open(); } void IDisposable.Dispose() { _connection.Close(); } } public class SomeDataClass : IDisposable { private SqlConnection _conn; //constructors and methods private void DoSomethingWithTheSqlConnection() { //some code excluded for brevity using (SqlCommand cmd = new SqlCommand("some sql query", _conn)) using(new SqlOpener(_conn)) { int countOfSomething = Convert.ToInt32(cmd.ExecuteScalar()); } //some code excluded for brevity } public void Dispose() { _conn.Dispose(); } }

Espero que ayude :)


Coloque el código de cierre de conexión dentro de un bloque "Finalmente" como lo muestra. Finalmente, los bloques se ejecutan antes de lanzar la excepción. Usar un bloque "usar" funciona igual de bien, pero el método explícito "Finalmente" me parece más claro.

Las declaraciones de uso son anticuadas para muchos desarrolladores, pero es posible que los desarrolladores más jóvenes no lo sepan.


Envuelva su código de manejo de base de datos dentro de un "uso"

using (SqlConnection conn = new SqlConnection (...)) { // Whatever happens in here, the connection is // disposed of (closed) at the end. }


Supongo que por "_SqlConnection.State == ConnectionState.Closed" significó! =.

Esto sin duda funcionará. Creo que es más habitual contener el objeto de conexión dentro de una sentencia using, pero lo que tienes es bueno si quieres reutilizar el mismo objeto de conexión por alguna razón.

Sin embargo, una cosa que definitivamente debería cambiar es el método Dispose (). No debe hacer referencia al objeto de conexión en disposición, ya que puede que ya se haya finalizado en ese punto. En su lugar, debe seguir el patrón de Disposición recomendado.


Ya que estás usando IDisposables de todos modos. Puede usar la palabra clave ''using'', que es básicamente equivalente a llamar a disponer en un bloque finally, pero se ve mejor.


Los documentos de MSDN lo dejan bastante claro ...

  • El método Close revierte cualquier transacción pendiente. A continuación, libera la conexión al grupo de conexiones o cierra la conexión si la agrupación de conexiones está deshabilitada.

Probablemente no haya (y no desee) deshabilitar la agrupación de conexiones, por lo que la agrupación finalmente gestiona el estado de la conexión después de llamar a "Cerrar". Esto podría ser importante ya que puede confundirse mirando desde el lado del servidor de la base de datos en todas las conexiones abiertas.

  • Una aplicación puede llamar Cerrar más de una vez. No se genera ninguna excepción.

Entonces, ¿por qué molestarse en las pruebas de Cerrado? Simplemente llame a Close ().

  • Close y Dispose son funcionalmente equivalentes.

Esta es la razón por la cual un bloque de uso da como resultado una conexión cerrada. usando llamadas Dispose para ti.

  • No llame a Close o Dispose en una conexión, un DataReader o cualquier otro objeto gestionado en el método Finalize de su clase.

Consejo de seguridad importante. Gracias, Egon.


no hay necesidad de probar ... por último, alrededor de un "uso", el uso es un intento ... por fin


.Net Framework mantiene un grupo de conexiones por un motivo. ¡Confía en ello! :) No tiene que escribir tanto código solo para conectarse a la base de datos y liberar la conexión.

Puedes usar la instrucción ''using'' y estar seguro de que ''IDBConnection.Release ()'' cerrará la conexión por ti.

Las ''soluciones'' altamente elaboradas tienden a dar como resultado un código defectuoso. Simple es mejor.


Vea esta pregunta para la respuesta:

Cerrar y desechar: ¿a qué llamar?

Si la duración de la conexión es una llamada a un solo método, use la función de uso del idioma para garantizar la limpieza adecuada de la conexión. Mientras que un bloque try/finally es funcionalmente el mismo, requiere más código y el IMO es menos legible. No es necesario verificar el estado de la conexión, puede llamar a Dispose independientemente y gestionará la limpieza de la conexión.

Si la duración de su conexión corresponde a la duración de una clase contenedora, implemente IDisposable y limpie la conexión en Dispose .