¿Cómo garantiza que el contexto de su base de datos se elimine correctamente cuando su colección perezosa ya no sea necesaria?

8

Estoy buscando un tipo de respuesta de mejores prácticas aquí.

Dado que las mejores prácticas para interactuar con las clases que implementan IDisposablees a través de la Usingdeclaración: ¿Cuál es la mejor práctica para usar la carga lenta de EF con MVC?

Método de controlador de ejemplo:

<HttpGet>
Public Function Schedule(ByVal id As Int64) As ActionResult

    Dim model As Schedule = Nothing
    Using database As dataContext = New dataContext
        model = (From s In database.Schedules Where s.ScheduleID = id Select s).FirstOrDefault
    End Using

    Return View(theSchedule)

End Function

Este ejemplo hace que la carga diferida no funcione porque la base de datos [dataContext] está eliminada cuando el modelo llega a la Vista.

Así que supongo que la pregunta es:
¿Cuáles son las mejores prácticas para usar la carga diferida en MVC? ¿Cómo garantiza que el contexto de su base de datos se elimine correctamente y que no cause pérdidas de memoria?

Sam Axe
fuente

Respuestas:

9

En general, no necesita usar Usingdeclaraciones con contextos de datos de Entity Framework. Las colecciones perezosas son uno de los motivos. Entonces su código simplemente sería:

<HttpGet>
Public Function Schedule(ByVal id As Int64) As ActionResult

    Dim model As Schedule = Nothing
    Dim database As dataContext = New dataContext
    model = (From s In database.Schedules Where s.ScheduleID = id Select s).FirstOrDefault

    Return View(model)

End Function

Los contextos de datos en Entity Framework están diseñados para abrir y cerrar conexiones según sea necesario, y se eliminan automáticamente cuando el objeto de contexto de datos ya no es necesario.

El comportamiento predeterminado de DbContext es que la conexión subyacente se abre automáticamente cada vez que se necesita y se cierra cuando ya no se necesita. Por ejemplo, cuando ejecuta una consulta e itera sobre los resultados de la consulta usando "foreach", la llamada a IEnumerable.GetEnumerator () hará que se abra la conexión, y cuando más tarde no haya más resultados disponibles, "foreach" se encargará de llamar Deseche en el enumerador, que cerrará la conexión.

El único momento del que deberías tener cuidado IDisposablees con Overridelos comportamientos predeterminados del contexto de datos.

Otras lecturas

¿Siempre tengo que llamar a Dispose en DBContext? No
Administrar DbContext de la manera correcta con Entity Framework 6: una guía detallada

Robert Harvey
fuente
No estoy seguro de que la segunda mitad de la cuarta oración sea correcta: "y se deshacen de sí mismos automáticamente cuando el objeto de contexto de datos queda fuera de alcance". Dado que el contexto de datos cae fuera del alcance por el tiempo, está en la Vista, usando su ejemplo, el contexto aún estaría disponible y, por lo tanto, ¿no se habría dispuesto? ¿Me estoy perdiendo de algo?
Sam Axe
No Tu derecho; Estaba un poco descuidado en mi redacción. La descripción correcta es que el DBContext se deshace de sí mismo cuando ya no es necesario; es decir, la colección perezosa se enumera o abandona por completo. Mira mis actualizaciones.
Robert Harvey
Muchas gracias por tomarse el tiempo de responder esto, Robert. Es muy apreciado.
Sam Axe
1
Tenga en cuenta que tener un DBContext que se comporte bien sin una usingdeclaración hace que sea mucho más agradable inyectar el DBContext, si lo desea.
Robert Harvey
DI es algo que buscaré en el futuro cercano, así que lo tendré en cuenta.
Sam Axe