¿Cuándo debería 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 extenso de las clases linq para devolver datos. Actualmente, para reflejar los datos a la base de datos, agregué un miembro de contexto de datos privados y un método de guardado público. El código se ve así:

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 simplificación excesiva, pero da la idea general. ¿Hay una mejor manera de manejar ese tipo de patrón? ¿Debo instanciar un nuevo contexto de datos cada vez que quiero visitar el db?

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

Hay algunas razones por las que implementamos IDisposable:

Si la lógica de la aplicación necesita mantenerse en una entidad más allá cuando se espera que el DataContext se use o sea válido, puede hacer cumplir ese contrato llamando a Dispose. Los cargadores diferidos en esa entidad seguirán haciendo referencia al DataContext e intentarán usarlo si algún código intenta navegar por las propiedades diferidas. Estos bashs fracasarán Dispose también fuerza a DataContext a volcar su caché de entidades materializadas para que una única entidad en caché no mantenga accidentalmente vivas todas las entidades materializadas a través de ese DataContext, que de lo contrario causaría lo que parece ser una pérdida de memoria.

La lógica que cierra automáticamente la conexión de DataContext se puede engañar para dejar la conexión abierta. El DataContext se basa en el código de la aplicación que enumera todos los resultados de una consulta, ya que llegar al final de un conjunto de resultados activa la conexión. Si la aplicación usa el método MoveNext de IEnumerable en lugar de una instrucción foreach en C # o VB, puede salir de la enumeración prematuramente. Si su aplicación tiene problemas con las conexiones que no se cierran y sospecha que el comportamiento de cierre automático no funciona, puede usar el patrón Dispose como una alternativa.

Pero, básicamente, no es necesario 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 “deshacerse de todo lo que implementa IDisposable” que recordar un montón de excepciones, pero es poco probable que se filtre un recurso si se olvida de deshacerse de él. eso.

Trata tu datacontext como un recurso. Y la regla de usar el recurso dice

“adquiere un recurso lo más tarde posible, libéralo tan pronto como sea seguro”

DataContext es bastante liviano y está destinado a la aplicación de la unidad de trabajo a medida que la utiliza. Sin embargo, no creo que conserve el DataContext en mi objeto. Es posible que desee examinar los patrones del repository si no va a utilizar el código generado por el diseñador para administrar sus objetos comerciales. El patrón de repository le permitirá trabajar con sus objetos separados del contexto de datos, luego volver a conectarlos antes de hacer actualizaciones, etc.

Personalmente, puedo vivir con el código generado por el diseñador de DBML en su mayor parte, con implementaciones de clase parciales para mi negocio y lógica de validación. También hago que el contexto de datos generados por el diseñador se abstraiga y herede de él para permitirme interceptar cosas como el método almacenado y los métodos de función con valores de tabla que se agregan directamente al contexto de datos y aplicar allí la lógica comercial.

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. Usar la fábrica me permite simular el contexto de datos de manera razonablemente fácil al (1) usar un contenedor alrededor de la clase de contexto de datos existente para que sea simulable (burlarse del envoltorio ya que DataContext no es fácilmente burlable) y (2) crear contextos Falsos / Simulacros y fábricas para crearlos. Ser capaz de crearlos a voluntad desde una fábrica hace que no tenga que mantener uno por largos periodos de tiempo.