Cuándo debo deshacerme de un contexto de datos


Actualmente estoy escribiendo una capa de acceso a datos para una aplicación. La capa de acceso hace un uso extensivo de las clases linq para devolver datos. Actualmente, para reflejar los datos en la base de datos, he agregado un miembro de contexto de datos privados y un método de guardado público. El código se ve algo como esto:

private DataContext myDb;
public static MyClass GetMyClassById(int id)
{
    DataContext db = new DataContext();
    MyClass result = (from item in db.MyClasss
                      where item.id == id
                      select item).Single();
    result.myDb = db;
    return result;
}

public void Save()
{
    db.SubmitChanges();
}

Eso es una burda simplificación, pero da la idea general. ¿Hay una mejor manera de manejar ese tipo de patrón? Debería estar instanciando un nuevo contexto de datos cada vez que ¿quieres visitar la db?

Author: Mykroft, 2008-12-23

3 answers

En realidad no importa demasiado. Le pregunté a Matt Warren del equipo de LINQ a SQL sobre esto hace un tiempo, y aquí está la respuesta:

Hay algunas razones por las que implementamos Identificable:

Si la lógica de la aplicación necesita mantenerse sobre una entidad más allá cuando el Se espera que se utilice DataContext o válido puede hacer cumplir ese contrato por llamando a Disponer. Cargadores diferidos en esa entidad seguirá haciendo referencia el DataContext y tratará de usarlo si cualquier código intenta navegar por el propiedades diferidas. Estos intentos fallará. Dispose también fuerza el DataContext para volcar su caché de entidades materializadas para que un solo la entidad en caché no lo hará accidentalmente mantener vivas todas las entidades materializadas a través de ese DataContext, que sería de lo contrario causar lo que parece ser un pérdida de memoria.

La lógica que se cierra automáticamente la conexión DataContext puede ser engañado para salir de la conexión abrir. El DataContext se basa en el código de aplicación que enumera todos resultados de una consulta desde llegar a el final de un conjunto de resultados desencadena la conexión para cerrar. Si el la aplicación utiliza la interfaz IEnumerable del Método MoveNext en lugar de un foreach declaración en C# o VB, puede salir la enumeración prematuramente. Si su la aplicación experimenta problemas con las conexiones no se cierran y usted sospeche el comportamiento de cierre automático no está funcionando puede usar la Disposición patrón como obra alrededor.

Pero básicamente no realmente necesita deshacerse de ellos en la mayoría de los casos, y eso es por diseño. Personalmente prefiero hacerlo de todos modos, ya que es más fácil seguir la regla de "disponer de todo lo que implemente identificable" que recordar un montón de excepciones a él, pero es poco probable que filtre un recurso si lo hace se olvida de disponer de él.

 65
Author: Jon Skeet,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-23 19:42:52

Trate su datacontext como un recurso. Y la regla de usar el recurso dice

"adquirir un recurso tan tarde como posible, lanzarlo tan pronto como su seguro"

 16
Author: Perpetualcoder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-23 19:38:12

DataContext es bastante ligero y está destinado a la unidad de aplicación de trabajo como lo está utilizando. Sin embargo, no creo que pudiera mantener el DataContext en mi objeto. Es posible que desee ver los patrones de repositorio si no va a usar el código generado por el diseñador para administrar sus objetos de negocio. El patrón de repositorio le permitirá trabajar con sus objetos separados del contexto de datos, luego volver a conectarlos antes de realizar actualizaciones, etc.

Personalmente, soy capaz de vivir con el código generado por DBML designer en su mayor parte, con implementaciones de clases parciales para mi negocio y lógica de validación. También hago que el contexto de datos generado por el diseñador sea abstracto y herede de él para permitirme interceptar cosas como procedimientos almacenados y métodos de funciones con valor de tabla que se agregan directamente al contexto de datos y aplican lógica de negocio allí.

Un patrón que he estado usando en ASP.NET MVC es inyectar una clase de fábrica que crea contextos de datos apropiados según sea necesario para las unidades de trabajo. El uso de la fábrica me permite simular el contexto de datos razonablemente fácil mediante (1) el uso de una envoltura alrededor de la clase de contexto de datos existente para que sea burlable (simular la envoltura ya que DataContext no es fácilmente burlable) y (2) la creación de contextos Falsos/Simulados y fábricas para crearlos. Ser capaz de crearlos a voluntad desde una fábrica hace que no tenga que mantener uno por largos períodos de tiempo.

 5
Author: tvanfosson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-12-23 19:31:12