2009-09-09 10 views
17

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 ellos. (Tengo experiencia en .Net 2.0, ADO.Net y WebForms)Entity Framework - Cómo debería instanciar mi objeto "Entidades"

Mi duda actual proviene de la forma en que estoy instalando mis objetos Entities.

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 estoy haciendo así porque lo encontré en algún blog de MSDN que parecía autoridad suficiente para mí que asumí esto era una manera correcta .
Sin embargo, me siento bastante fácil al respecto. A pesar de que me ahorra mucho código, yo estoy acostumbrado a hacer:

using (NorthWindEntities db = new NorthWindEntities() { 
} 

En cada método único que necesita una conexión, y si ese método llama a otros que necesitaré, ya pasará db un parámetro para ellos. 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 llamar a su método Dispose(), y no lo estoy.

¿Qué opina sobre esto?
¿Es correcto instanciar el objeto Entidades como lo estoy haciendo? ¿Debería ocuparse de sus conexiones abriendo y cerrando para cada consulta?
¿O debería eliminarlo explícitamente con una cláusula using()?

Gracias!

Respuesta

21

El propio controlador implementa IDisposable. De modo que puede anular Eliminar y deshacerse de cualquier cosa (como un contexto de objeto) que inicialice cuando se crea una instancia del controlador.

El controlador solo dura tanto como una sola solicitud. Así que 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 haya sido procesada. Por lo tanto, si crea su ObjectContext en una instrucción using dentro de la acción, ObjectContext se eliminará antes de que se visualice la vista. Así que será mejor que haya leído algo del contexto que necesita antes de que la acción finalice. Si el modelo que pasa a la vista es una lista diferida como IQueryable, habrá dispuesto el contexto antes de que se represente la vista, lo que provocará una excepción cuando la vista intente enumerar IQueryable.

Por el contrario, si inicializa el ObjectContext cuando se inicializa el controlador (o escribe un código de inicialización lento causando que se inicialice cuando se ejecuta la acción) y desecha el ObjectContext en el Controller.Dispose, entonces el contexto seguirá estar cerca cuando se represente la vista. En este caso, es seguro pasar un IQueryable a la vista. El controlador se eliminará poco después de que se visualice la vista.

Finalmente, sería negligente si no señalara que probablemente sea una mala idea que su Controlador tenga conocimiento del Entity Framework en absoluto. Considere usar un ensamble 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 sobre esto.

+0

Ok, eso tiene sentido. Ahora, la pregunta es ... ¿Estoy haciendo las cosas incorrectamente? ¿Realmente necesito deshacerme del objeto Entidades? ¿Qué sucede si no? ¿Estaré "filtrando" conexiones al Servidor SQL? –

+1

ObjectContext.Dispose no hace mucho (ver Reflector). Pero es razonable suponer que podría cambiar y usted * debería * eliminarlo. –

3

Estás haciendo un buen punto aquí.¿Cuánto tiempo debería durar el ObjectContext? Todos los libros de patrones y prácticas (como el Microsoft-NET-Architecting-Applications de Dino Esposito) indican que un DataContext no debe durar mucho tiempo ni debe almacenarse en caché.

Me preguntaba por qué no tener, en su caso, una clase ControllerBase (no conozco la implementación de MVC, así que tengan paciencia) donde se inicia el ObjectContext una vez para todos los controladores. Especialmente piense en el Identity Map Pattern, que ya ha sido implementado por Entity Framework. Aunque necesite llamar a otro controlador como su PostsController, aún así funcionaría con el mismo contexto y también mejoraría el rendimiento.

Cuestiones relacionadas