2012-03-21 14 views
14

Si los métodos/funciones que voy a llamar implican la necesidad de una SqlConnection abierta, abriré esto en el método que llama a la función. Por ejemplo:¿Es mejor pasar una SqlConnection abierta como parámetro, o llamar a una nueva en cada método?

protected static void btnSubmit(){ 
    conn.Open(); 
    myMethod(someParam, conn); 
    conn.Close(); 
} 

protected static void myMethod(object someParam, SqlConnection conn){ 
    //Some SQL commands etc here.. 
} 

hago esto para que yo:

  • Sólo alguna vez se abren y cierran 1 SqlConnection por proceso

Sin embargo, sería mejor para estructurar mi código como tal :

protected static void btnSubmit(){ 
    myMethod(someParam); 
} 

protected static void myMethod(object someParam){ 
    SqlConnection conn = New SqlConnection("....."); 
    conn.Open(); 
    //Some SQL commands etc here.. 
    conn.Close(); 
} 

La ventaja que veo al estructurarlo de esta manera es:

  • no tengo para pasar un parámetro adicional para cada método
  • Si después de la línea del método ya no tiene un comando SQL, no es un parámetro no utilizado se llama cada vez que

La desventaja que veo a esto, es:

  • Si myMethod es un método iterativo y, a continuación, cuando se llama a sí mismo que va a ser la apertura de otra SqlConnection, y así sucesivamente, y así sucesivamente ..
  • Si btnSubmit llama a varios métodos que requieren una SqlConnection, cada uno abrirá y cerrará una nueva conexión.

¿Cuál es la mejor manera de hacerlo, y cuál es la más comúnmente practicada?

Respuesta

16

ADO.NET utiliza la agrupación de conexiones, por lo que reutiliza automáticamente la conexión ya abierta, incluso cuando crea que está abriendo una nueva conexión. Teniendo eso en mente, no hay realmente ninguna razón para pasar la conexión a través de su código (como parámetro). Eso hará que tu código sea mucho más limpio con el mismo rendimiento que cuando pasas la conexión como parámetro.

Más detalles here

también (y esto es muy importante), por favor, utilice el "uso" de palabras clave. De esa manera, no tendrá que desabilitar el cierre de la conexión y la limpieza, ya que su código tal como está escrito ahora no se ocupa de cerrar las conexiones, por lo que en el caso de alguna excepción, puede terminar presionando el límite de conexión. tu servidor Ir con algo como esto:

using(var connection = new SqlConnection(<connection_string>)) 
{ 
    connection.Open(); 
    using(var command = connection.CreateCommand()) 
    { 

    } 
} 

Como se puede ver, no hay necesidad de llamar a Connection.close() o hacer frente a las excepciones y cerrar la conexión en el bloque de finally, ya que es un "trabajo" para el bloque "usar".

Además, una nota importante ... las transacciones no se pasan por sondeo de conexión, por lo que si desea mantener su transacción entre llamadas de método, tendrá que pasar su conexión (y esa es la única razón por la que puedo pensar por qué deberías hacer eso).

+0

Entonces, si abro 100 objetos SqlConnection diferentes, todos para la misma base de datos/inicio de sesión, ¿esto no está poniendo más presión en el procesamiento? – Curt

+0

Saludos por los detalles adicionales. Entonces, es una buena práctica poner mi declaración 'using' en' myMethod' (usando mi ejemplo) Siempre lo he evitado, por motivos de rendimiento, pero si no hace ninguna diferencia, ¡será más nítido! – Curt

+1

Si no lo crees, haz una prueba y pruébalo :) Verás que no hay diferencia (al menos no se nota). Hay una propiedad en el grupo de conexiones que dice cuál es el tamaño máximo de la agrupación (creo que 100 es un valor predeterminado), eche un vistazo aquí: http://msdn.microsoft.com/en-us/library/8xx3tyca(v= vs.71) .aspx dentro de "Control de agrupación de conexiones con palabras clave de cadena de conexión" sección –

10

El mejor patrón para usar es Repository + UnitOfWork patrones.

Así que el repositorio se crea y pasa el UnitOfWork que contiene la conexión. Una vez finalizado el trabajo, se desecha UnitOfWork.

// Pseudocode 
using(UnitOfWork uow = new UnitOfWork()) 
{ 
    Repository.Init(uow); 
    Repository.SaveInDb(stuff); 
} 

y la unidad de trabajo:

// PseudoCode 
class UnitOfWork : IDisposable 
{ 
    public UnitOfWork() 
    { 
     conn = new SqlConnection(); 
     conn.Open(); 
    } 

    public void Dispose() 
    { 
     conn.Close(); 
    } 

.... 

} 

Esto es lo que siempre uso.

Algunas personas prefieren un enfoque más simple donde el repositorio posee conexión. Esto es más simple, pero en caso de que necesite una transacción en varios repositorios, no funcionará.

+0

+1 por incluso incluso aludir ligeramente al hecho de que los límites de las transacciones deberían ser una consideración al actualizar una base de datos. – mwardm

Cuestiones relacionadas