2009-04-13 16 views

Respuesta

94

Trate de evitar el uso de lectores de esta manera:

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()) 
     { 
       //do something 
     } 
} 
reader.Close(); // <- too easy to forget 
reader.Dispose(); // <- too easy to forget 
connection.Close(); // <- too easy to forget 

En su lugar, se envuelven en using:

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()) 
       { 
        //do something 
       } 
      } 
     } // reader closed and disposed up here 

    } // command disposed here 

} //connection closed and disposed here 

La instrucción using asegurarán una eliminación correcta del objeto y liberación de recursos.

Si lo olvida, estará dejando la limpieza al recolector de basura, lo que podría llevar un tiempo.

+21

No necesita la instrucción .Close() en ninguna de las dos muestras: se trata con la llamada .Dispose(). –

+0

Bien, marqué el cierre como opcional en el código – Codebrain

+0

Esta muestra no muestra la conexión subyacente cerrada/eliminada, que es lo más importante. – Joe

9

Para estar seguro, ajuste cada objeto SqlDataReader en using statement.

+0

Justo lo suficiente. Sin embargo, ¿realmente hace una diferencia en el rendimiento si no hay una instrucción using? –

+0

Una instrucción de uso es lo mismo que ajustar el código de DataReader en un bloque try..finally ... con el método de cierre/eliminación en la sección finally. Básicamente, simplemente "garantiza" que el objeto será eliminado correctamente. – Todd

+0

Esto es directamente desde el enlace que proporcioné: "La sentencia using asegura que se llama a Dispose incluso si se produce una excepción mientras se están llamando métodos al objeto". – Kon

4

Simplemente ajuste su SQLDataReader con la instrucción "using". Eso debería encargarse de la mayoría de sus problemas.

40

Tenga en cuenta que eliminar un SqlDataReader instanciado mediante SqlCommand.ExecuteReader() no cerrar/eliminar la conexión subyacente.

Hay dos patrones comunes. En la primera, el lector se abre y se cierra en el ámbito 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 de datos abierta una conexión y devuelve un lector. En este caso, es importante que el lector devuelto se abra usando CommandBehavior.CloseConnection, de modo que al cerrar/eliminar el lector se cierre la conexión subyacente. El patrón se ve algo como esto:

y el código de llamada sólo necesita disponer el lector de este modo:

using(SqlDataReader reader = ExecuteReader(...)) 
{ 
    ... do your stuff ... 
} // reader and connection are closed here. 
+2

No hay un método Close() en el objeto SqlCommand. – Dave

+0

En el segundo fragmento de código donde el método devuelve un SqlDataReader, el comando no se elimina. ¿Está bien y está bien disponer el comando (incluirlo en un bloque de uso) y luego devolver el lector? – alwayslearning

+0

@alwayslearning ese es exactamente el escenario que tengo ... ¿puede cerrar/eliminar el SqlCommand cuando devuelve el SqlDataReader a la persona que llama? – ganders

Cuestiones relacionadas