example ejemplos ejemplo c# using sqlconnection

c# - ejemplos - en un bloque "usar", ¿está cerrada una SqlConnection por devolución o excepción?



sqlconnection c# example sql server (7)

  1. Sí.

De cualquier manera, cuando se sale del bloque de uso (ya sea por finalización exitosa o por error), se cierra.

Aunque creo que sería mejor organizarse así porque es mucho más fácil ver lo que sucederá, incluso para el nuevo programador de mantenimiento que lo respaldará más adelante:

using (SqlConnection connection = new SqlConnection(connectionString)) { int employeeID = findEmployeeID(); try { connection.Open(); SqlCommand command = new SqlCommand("UpdateEmployeeTable", connection); command.CommandType = CommandType.StoredProcedure; command.Parameters.Add(new SqlParameter("@EmployeeID", employeeID)); command.CommandTimeout = 5; command.ExecuteNonQuery(); } catch (Exception) { /*Handle error*/ } }

Primera pregunta:
Digamos que tengo

using (SqlConnection connection = new SqlConnection(connectionString)) { connection.Open(); string storedProc = "GetData"; SqlCommand command = new SqlCommand(storedProc, connection); command.CommandType = CommandType.StoredProcedure; command.Parameters.Add(new SqlParameter("@EmployeeID", employeeID)); return (byte[])command.ExecuteScalar(); }

¿La conexión se cierra? Porque técnicamente nunca llegamos a la última } como regresamos antes.

Segunda pregunta:
Esta vez tengo:

try { using (SqlConnection connection = new SqlConnection(connectionString)) { int employeeID = findEmployeeID(); connection.Open(); SqlCommand command = new SqlCommand("UpdateEmployeeTable", connection); command.CommandType = CommandType.StoredProcedure; command.Parameters.Add(new SqlParameter("@EmployeeID", employeeID)); command.CommandTimeout = 5; command.ExecuteNonQuery(); } } catch (Exception) { /*Handle error*/ }

Ahora, di que en alguna parte del try obtenemos un error y queda atrapado. ¿La conexión aún se cierra? Porque, de nuevo, omitimos el resto del código en la try e ingresamos directamente a la declaración catch .

¿Estoy pensando demasiado linealmente en cómo funciona el trabajo? es decir, ¿se llama a Dispose() simplemente cuando dejamos el ámbito de using ?


Aquí está mi Plantilla. Todo lo que necesita para seleccionar datos de un servidor SQL. La conexión está cerrada y eliminada, y se detectan errores de conexión y ejecución.

string connString = System.Configuration.ConfigurationManager.ConnectionStrings["CompanyServer"].ConnectionString; string selectStatement = @" SELECT TOP 1 Person FROM CorporateOffice WHERE HeadUpAss = 1 AND Title LIKE ''C-Level%'' ORDER BY IntelligenceQuotient DESC "; using (SqlConnection conn = new SqlConnection(connString)) { using (SqlCommand comm = new SqlCommand(selectStatement, conn)) { try { conn.Open(); using (SqlDataReader dr = comm.ExecuteReader()) { if (dr.HasRows) { while (dr.Read()) { Console.WriteLine(dr["Person"].ToString()); } } else Console.WriteLine("No C-Level with Head Up Ass Found!? (Very Odd)"); } } catch (Exception e) { Console.WriteLine("Error: " + e.Message); } if (conn.State == System.Data.ConnectionState.Open) conn.Close(); } }

* Revisado: 2015-11-09 *
Como lo sugirió NickG; Si demasiadas llaves te molestan, formatea así ...

using (SqlConnection conn = new SqlConnection(connString)) using (SqlCommand comm = new SqlCommand(selectStatement, conn)) { try { conn.Open(); using (SqlDataReader dr = comm.ExecuteReader()) if (dr.HasRows) while (dr.Read()) Console.WriteLine(dr["Person"].ToString()); else Console.WriteLine("No C-Level with Head Up Ass Found!? (Very Odd)"); } catch (Exception e) { Console.WriteLine("Error: " + e.Message); } if (conn.State == System.Data.ConnectionState.Open) conn.Close(); }

Por otra parte, si trabajas para juegos de EA o DayBreak, también puedes renunciar a los saltos de línea porque son solo para personas que tienen que volver y mirar tu código más tarde y ¿a quién realmente le importa? ¿Estoy en lo cierto? Me refiero a 1 línea en lugar de 23 significa que soy un mejor programador, ¿verdad?

using (SqlConnection conn = new SqlConnection(connString)) using (SqlCommand comm = new SqlCommand(selectStatement, conn)) { try { conn.Open(); using (SqlDataReader dr = comm.ExecuteReader()) if (dr.HasRows) while (dr.Read()) Console.WriteLine(dr["Person"].ToString()); else Console.WriteLine("No C-Level with Head Up Ass Found!? (Very Odd)"); } catch (Exception e) { Console.WriteLine("Error: " + e.Message); } if (conn.State == System.Data.ConnectionState.Open) conn.Close(); }

Phew ... OK. Lo saqué de mi sistema y he terminado de divertirme por un tiempo. Continua.


Dispose simplemente se llama cuando sales del ámbito de uso. La intención de "usar" es brindarles a los desarrolladores una forma garantizada de asegurarse de que los recursos se eliminen.

Desde MSDN :

Se puede salir de una instrucción using ya sea cuando se llega al final de la sentencia using o si se lanza una excepción y el control abandona el bloque de instrucciones antes del final de la instrucción.


En su primer ejemplo, el compilador de C # traducirá la declaración de uso a lo siguiente:

SqlConnection connection = new SqlConnection(connectionString)); try { connection.Open(); string storedProc = "GetData"; SqlCommand command = new SqlCommand(storedProc, connection); command.CommandType = CommandType.StoredProcedure; command.Parameters.Add(new SqlParameter("@EmployeeID", employeeID)); return (byte[])command.ExecuteScalar(); } finally { connection.Dispose(); }

Finalmente, siempre se invocarán las declaraciones antes de que regrese una función y, por lo tanto, la conexión siempre estará cerrada / desechada.

Entonces, en su segundo ejemplo, el código se compilará de la siguiente manera:

try { try { connection.Open(); string storedProc = "GetData"; SqlCommand command = new SqlCommand(storedProc, connection); command.CommandType = CommandType.StoredProcedure; command.Parameters.Add(new SqlParameter("@EmployeeID", employeeID)); return (byte[])command.ExecuteScalar(); } finally { connection.Dispose(); } } catch (Exception) { }

La excepción se detectará en la declaración final y la conexión se cerrará. La excepción no se verá en la cláusula de captura externa.


Escribí dos instrucciones de uso dentro de un bloque try / catch y pude ver que la excepción se estaba atrapando de la misma manera si se coloca dentro de la instrucción de uso interno justo como el example ShaneLS.

try { using (var con = new SqlConnection(@"Data Source=...")) { var cad = "INSERT INTO table VALUES (@r1,@r2,@r3)"; using (var insertCommand = new SqlCommand(cad, con)) { insertCommand.Parameters.AddWithValue("@r1", atxt); insertCommand.Parameters.AddWithValue("@r2", btxt); insertCommand.Parameters.AddWithValue("@r3", ctxt); con.Open(); insertCommand.ExecuteNonQuery(); } } } catch (Exception ex) { MessageBox.Show("Error: " + ex.Message, "UsingTest", MessageBoxButtons.OK, MessageBoxIcon.Error); }

No importa dónde está el try / catch colocado, la excepción se detectará sin problemas.


Sí a ambas preguntas. La instrucción using se compila en un bloque try / finally

using (SqlConnection connection = new SqlConnection(connectionString)) { }

es lo mismo que

SqlConnection connection = null; try { connection = new SqlConnection(connectionString); } finally { if(connection != null) ((IDisposable)connection).Dispose(); }

Editar: reparando el lanzamiento en Desechable http://msdn.microsoft.com/en-us/library/yh598w02.aspx


Using genera un try / finally alrededor del objeto asignado y llama a Dispose() por usted.

Le ahorra la molestia de crear manualmente el bloque try / finally y llamar a Dispose()