Trate de evitar el uso de lectores como este:
SqlConnection connection = new SqlConnection("connection string");
SqlCommand cmd = new SqlCommand("SELECT * FROM SomeTable", connection);
SqlDataReader reader = cmd.ExecuteReader();
connection.Open();
if (reader != null)
{
while (reader.Read())
{
}
}
reader.Close();
reader.Dispose();
connection.Close();
En su lugar, envuélvalos en declaraciones de uso:
using(SqlConnection connection = new SqlConnection("connection string"))
{
connection.Open();
using(SqlCommand cmd = new SqlCommand("SELECT * FROM SomeTable", connection))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
if (reader != null)
{
while (reader.Read())
{
}
}
}
}
}
La declaración de uso asegurará la correcta eliminación del objeto y la liberación de recursos.
Si lo olvidas, dejarás la limpieza en manos del recolector de basura, lo que podría llevar un tiempo.
Tenga en cuenta que eliminar un SqlDataReader instanciado mediante SqlCommand.ExecuteReader () no cerrará / eliminará la conexión subyacente.
Hay dos patrones comunes. En el primero, el lector se abre y se cierra dentro del alcance de la conexión:
using(SqlConnection connection = ...) { connection.Open(); ... using(SqlCommand command = ...) { using(SqlDataReader reader = command.ExecuteReader()) { ... do your stuff ... } // reader is closed/disposed here } // command is closed/disposed here } // connection is closed/disposed here
A veces es conveniente tener un método de acceso a datos para abrir una conexión y devolver un lector. En este caso, es importante que el lector devuelto se abra usando CommandBehavior.CloseConnection, de modo que cerrar / eliminar el lector cerrará la conexión subyacente. El patrón se parece a esto:
public SqlDataReader ExecuteReader(string commandText) { SqlConnection connection = new SqlConnection(...); try { connection.Open(); using(SqlCommand command = new SqlCommand(commandText, connection)) { return command.ExecuteReader(CommandBehavior.CloseConnection); } } catch { // Close connection before rethrowing connection.Close(); throw; } }
y el código de llamada solo necesita disponer al lector de esta manera:
using(SqlDataReader reader = ExecuteReader(...)) { ... do your stuff ... } // reader and connection are closed here.
fuente
using
s, entonces llama a dispose en elfinally {}
bloque después de la captura. De la forma en que esto está escrito, los comandos exitosos nunca se cerrarán o eliminarán.Para estar seguro, envuelva cada objeto SqlDataReader en una instrucción using .
fuente
Simplemente envuelva su SQLDataReader con la declaración "using". Eso debería solucionar la mayoría de sus problemas.
fuente