2012-04-13 22 views
8

Si quiero ejecutar múltiples consultas SELECT en tablas diferentes, ¿puedo usar el mismo SqlDataReader y SqlConnection para todas? Sería lo siguiente sabio? (Escribí esto rápidamente, por lo que carece de try/catch):Reutilización de SqlConnection y SqlDataReader

MySqlCommand myCommand = new MySqlCommand("SELECT * FROM table1", myConnection); 

myConnection.Open(); 
SqlDataReader myDataReader = myCommand.ExecuteReader(); 

while(myReader.Read()) 
{ 
    //Perform work. 
} 

myCommand.commandText = "SELECT * FROM table2"; 

myReader = myCommand.ExecuteReader(); 

while(myReader.Read()) 
{ 
    //Perform more work 
} 

myReader.Close(); 
myConnection.Close(); 

Muchas gracias.

+0

Debería considerar usar Entity Framework. –

+1

Quizás útil: http://stackoverflow.com/questions/9705637/executereader-requires-an-open-and-available-connection-theconnections-curren/9707060 # 9707060 –

+1

¿Su código anterior da algún error? Si no, entonces seguramente está bien. – sarwar026

Respuesta

20

Puede usar la misma conexión para cada uno de ellos, siempre que no intente ejecutar varias consultas al mismo tiempo en la misma conexión desde diferentes subprocesos.

En cuanto al lector de datos, en realidad no está reutilizando el lector, cada llamada a ExecuteReader devuelve una nueva instancia de un nuevo lector, todo lo que está reutilizando es la variable que mantiene la referencia al lector. Aquí, en caso de que exista un problema, solo está cerrando explícitamente el último lector y dejando el primero para ser GC en algún momento posterior.

También puede reutilizar el comando, pero recuerde que si proporciona parámetros, etc., deberá borrarlos para la siguiente consulta, a menos que también se apliquen a la siguiente consulta.

Debe usar los bloques try/finally para asegurarse de limpiar los recursos, o aquí hay un cambio rápido a su código para usar las declaraciones using para asegurar la limpieza de recursos incluso si hay una excepción que impide el resto del código de ejecutar.

using (var myConnection = GetTheConnection()) 
{ 
    myConnection.Open(); 

    var myCommand = new MySqlCommand("SELECT * FROM table1", myConnection)) 
    using (var myDataReader = myCommand.ExecuteReader()) 
    { 
    while(myReader.Read()) 
    { 
     //Perform work. 
    } 
    } // Reader will be Disposed/Closed here 

    myCommand.commandText = "SELECT * FROM table2"; 
    using (var myReader = myCommand.ExecuteReader()) 
    { 
    while(myReader.Read()) 
    { 
     //Perform more work 
    } 
    } // Reader will be Disposed/Closed here 
} // Connection will be Disposed/Closed here 

Nota: GetTheConnection es sólo una función de marcador de posición para lo que cada vez el mecanismo que está utilizando para obtener su instancia de conexión.

+0

Gracias. Así que supongo que solo necesito cerrar el objeto lector después de cada ejecución. – PaulG

+1

Actualmente estoy suministrando parámetros para el SqlCommand, supongo que debería usar myCommand.Parameters.Clear(). Muchas gracias. – PaulG

+2

@PaulG, como regla general, cada vez que una clase implemente un IDisposable, debe desecharlo lo antes posible. En el caso de los lectores, vinculan los recursos del servidor de bases de datos hasta que se cierran o eliminan, por lo que desea deshacerse de ellos tan pronto como haya terminado con ellos. Ahora veo que está utilizando MySQL, así que no sé cuál es el uso de recursos, pero para los sistemas basados ​​en servidor DBMS como Oracle o SQL Server, este es el caso, y siempre debe asumir que este es el caso. –

2

Generalmente uso adaptadores, así que estoy oxidado sobre los detalles del lector, pero creo que está en el camino correcto.

Un elemento de la nota en su código es que cada llamada a ExecuteReader debe generar un nuevo lector de datos. Es posible que esté reutilizando el nombre de la variable, pero la referencia al lector existente se descarta y se reemplaza por una nueva en cada llamada. Señalando, cierre el lector anterior antes de usar ExecuteReader para obtener uno nuevo.