2011-10-21 25 views
7

He estado incorporando mis objetos OracleConnection y OracleCommand en las instrucciones de USO durante un tiempo, sin embargo, después de ejecutar el analizador de código, descubro que OracleParameter también implementa IDisposable. Es el siguiente código correcto? ¿Hay una mejor técnica para legibilidad o estructura? A primera vista, parece estar atestado de instrucciones USING:C# IDisposable Uso: Mejores prácticas

using (OracleConnection conn = new OracleConnection(connectionstring)) 
{ 
    conn.Open(); 
    using (OracleCommand cmd = new OracleCommand(sql, conn)) 
    { 
     cmd.BindByName = true; 

     using (OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, System.Data.ParameterDirection.Input)) 
     { 
      param1.Value = int.Parse(value1); 
      cmd.Parameters.Add(param1); 
     } 

     using (OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, System.Data.ParameterDirection.Input)) 
     { 
      param2.Value = value2; 
      cmd.Parameters.Add(param2); 
     } 

     using (OracleDataReader dr = cmd.ExecuteReader()) 
     { 
      // loop data here... 
     } 
    } 
} 

Respuesta

7

desea deshacerse de los parámetros sólo al final de su uso, incluso durante la consulta (y, posiblemente, la lectura de los resultados):

using (OracleConnection conn = new OracleConnection(connectionstring)) 
{ 
    conn.Open(); 
    using (OracleCommand cmd = new OracleCommand(sql, conn)) 
    { 
     cmd.BindByName = true; 

     using (OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, System.Data.ParameterDirection.Input)) 
     using (OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, System.Data.ParameterDirection.Input)) 
     { 
      param1.Value = int.Parse(value1); 
      cmd.Parameters.Add(param1); 
      param2.Value = value2; 
      cmd.Parameters.Add(param2); 

      using (OracleDataReader dr = cmd.ExecuteReader()) 
      { 
       // loop data here... 
      } 
     } 
    } 
} 

Tenga en cuenta que usted puede poner múltiples using declaraciones en una fila. Esto se debe a que, al igual que la declaración if,

  1. Una declaración using se considera una simple declaración (incluso con un bloque); y
  2. Una declaración using puede tomar un bloque o una declaración debajo.
+0

Aunque hubo muchas respuestas similares, valoré que haya proporcionado ejemplos y comentarios. – Shawn

+0

Gracias! Me alegro de poder ser de ayuda. :-) –

1

No estoy seguro de que funcione correctamente. Considere que al final del uso, ambos parámetros deberían haberse eliminado. El hecho de que su objeto cmd.Parameters todavía tenga una referencia a ellos no excluye lo que puede estar sucediendo en el método de eliminación OracleParameter. Para todos los propósitos intensivos, el desarrollador de ese objeto en particular puede estar borrando los campos que su OracleCommand espera llenar.

Hay un peligro allí. Si está absolutamente seguro de que desea deshacerse de su OracleParameters correctamente, le sugiero que los deseche después de usar el OracleDataReader.

Recuerde que generalmente llama al Dispose cuando termina de usar el objeto. Le está diciendo que libere todos los recursos que está reteniendo en el grupo. Si no ha terminado de usar un objeto, no lo arroje prematuramente.

0

No, esto no es correcto porque está eliminando los parámetros incluso antes de usarlos.

su lugar debe por lo que como este

OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, System.Data.ParameterDirection.Input); 

param1.Value = int.Parse(value1); 
cmd.Parameters.Add(param1); 


OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, System.Data.ParameterDirection.Input); 

param2.Value = value2; 
cmd.Parameters.Add(param2); 


using (OracleDataReader dr = cmd.ExecuteReader()) 
{ 
    // loop data here... 
} 

param1.dispose(); 
param2.dispose(); 
1
using (OracleConnection conn = new OracleConnection(connectionstring)) 
using (OracleCommand cmd = new OracleCommand(sql, conn)) 
using (OracleParameter param1 = new OracleParameter("p1", OracleDbType.Int32, 
     System.Data.ParameterDirection.Input)) 
using (OracleParameter param2 = new OracleParameter("p2", OracleDbType.Varchar2, 
     System.Data.ParameterDirection.Input)) 
} 
    conn.Open(); 
    cmd.BindByName = true; 

    param1.Value = int.Parse(value1); 
    cmd.Parameters.Add(param1); 

    param2.Value = value2; 
    cmd.Parameters.Add(param2); 

    using (OracleDataReader dr = cmd.ExecuteReader()) 
    { 
     // loop data here... 
    } 
} 
0

se puede mirar el código fuente de conexión y mando, no se disponga de los parámetros? si los objetos de conexión o de comando eliminan el patrón envuelve los parámetros y los descarta cuando quedan eliminados. deberías preocuparte por eso que creo que debería/debería.

0

Este código es incorrecto. los parámetros que crea siguen utilizándose fuera del alcance de la declaración using porque los agrega a la colección de parámetros, pero la instrucción using llamará a Dispose en los parámetros del control que salga del ámbito. Lo que significa que cuando llegará el momento de utilizar los parámetros dentro de la theya comando se habrá de disoised ya

0

Según MSDN, sólo tiene que utilizar para usingConnection y DataReader objetos. Nunca he visto using (o .Dispose()) usado con objetos de parámetros ADO.NET. Si esto fuera necesario o incluso deseable, creo que ya habría surgido en los últimos 10 años.

+2

MSDN está hablando de los objetos proporcionados por el BCL. La implementación de Oracle de estos puede muy bien requerir la eliminación de los parámetros. ¿Por qué iban a implementar IDisposable si no estaban destinados a Disposed? –

+0

O muy bien no pueden. Nunca he visto ningún código ADO.NET (para la implementación de Oracle o de otra persona) que llama Dispose() en un objeto de parámetro o lo coloca en un bloque 'using'. Nuevamente, si los parámetros de eliminación fueran necesarios, esto habría levantado su cabeza hace mucho tiempo. – MusiGenesis

+2

¿Entonces su consejo es que, aunque un objeto implementa IDisposble, no lo elimine a menos que se sepa que es un problema? Me parece un mal consejo. –