Pregunta

Soy un novato total en Entity Framework y ASP.Net MVC, habiendo aprendido principalmente de tutoriales, sin tener una comprensión profunda de ninguno de los dos. (Tengo experiencia en .Net 2.0, ADO.Net y WebForms)

Mi duda actual proviene de la forma en que instalo los objetos de Entidades.

Básicamente estoy haciendo esto en mis controladores:

public class PostsController : Controller {

    private NorthWindEntities db = new NorthWindEntities();

    public ActionResult Index() {
            // Use the db object here, never explicitly Close/Dispose it
    }
}

Lo hago así porque lo encontré en un blog de MSDN que me pareció lo suficientemente autoritario como para suponer que esta era la forma correcta.
Sin embargo, me siento bastante poco fácil acerca de esto. Aunque me ahorra mucho código, estoy acostumbrado a hacerlo:

using (NorthWindEntities db = new NorthWindEntities() {
}

En cada método único que necesita una conexión, y si ese método llama a otros que lo necesitarán, les pasará db como parámetro. Así es como hice todo con mis objetos de conexión antes de que existiera Linq-to-SQL.

La otra cosa que me inquieta es que NorthWindEntities implementa IDisposable, que por convención significa que debería estar llamando a su método Dispose (), y no lo estoy.

¿Qué piensas de esto?
¿Es correcto instanciar el objeto Entidades como lo estoy haciendo? ¿Debería cuidar sus conexiones abriéndolas y cerrándolas para cada consulta?
¿O debería eliminarlo explícitamente con una cláusula using ()?

¡Gracias!

¿Fue útil?

Solución

El propio controlador implementa IDisposable. Por lo tanto, puede anular la eliminación y disposición de cualquier cosa (como un contexto de objeto) que inicialice cuando se ejecute la instancia del controlador.

El controlador solo tiene vida mientras una sola solicitud. Por lo tanto, tener un uso dentro de una acción y tener un contexto de objeto para todo el controlador es exactamente el mismo número de contextos: 1.

La gran diferencia entre estos dos métodos es que la acción se habrá completado antes de que la vista se haya procesado. Entonces, si crea su ObjectContext en una declaración usando dentro de la acción, el ObjectContext se habrá eliminado antes de que la vista se haya procesado. Por lo tanto, es mejor que haya leído algo del contexto que necesita antes de que se complete la acción. Si el modelo que pasa a la vista es una lista perezosa como un IQueryable, habrá eliminado el contexto antes de que se genere la vista, causando una excepción cuando la vista intente enumerar el IQueryable.

Por el contrario, si inicializa el ObjectContext cuando se inicia el controlador (o escribe un código de inicialización perezoso que hace que se inicialice cuando se ejecuta la acción) y elimina el ObjectContext en el Controller.Dispose, entonces el contexto aún será alrededor cuando la vista se renderiza. En este caso, es seguro pasar un IQueryable a la vista. El controlador se eliminará poco después de que se haya procesado la vista.

Finalmente, sería negligente si no señalara que probablemente sea una mala idea que tu Controlador esté al tanto del Entity Framework. Considere el uso de un conjunto separado para su modelo y el patrón de repositorio para que el controlador hable con el modelo. Una búsqueda en Google aparecerá bastante en esto.

Otros consejos

Estás haciendo un buen punto aquí. ¿Por cuánto tiempo debería estar vivo el ObjectContext? Todos los patrones y libros de prácticas (como el Microsoft-NET-Architecting-Applications ) te dice que un DataContext no debe durar mucho tiempo, ni se debe almacenar en caché.

Me preguntaba por qué no tener, en su caso, una clase ControllerBase (no conozco la implementación de MVC, así que tenga paciencia conmigo), donde ObjectContext se inicia una vez para todos los controladores. Especialmente piense en el Patrón del mapa de identidad , que ya está implementado por Entity Framework. A pesar de que necesita llamar a otro controlador como PostsController, seguirá funcionando con el mismo Contexto y también mejorará el rendimiento.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top