2009-09-09 9 views
17

Je suis un débutant total chez Entity Framework et ASP.Net MVC, ayant appris la plupart du temps à partir de tutoriels, sans avoir une compréhension profonde de l'un ou l'autre. (J'ai de l'expérience sur .Net 2.0, ADO.Net et WebForms)Entity Framework - Comment utiliser mon objet "Entities"

Mon doute actuel provient de la façon dont j'instance mes objets Entités.

En fait, je le fais dans mes contrôleurs:

public class PostsController : Controller { 

    private NorthWindEntities db = new NorthWindEntities(); 

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

Je fais comme ça parce que je qui me semblait assez autoritaire pour trouvé dans certains blog de MSDN que je suppose que c'était une bonne façon .
Cependant, je me sens pas très facile à ce sujet. Bien qu'il me sauve beaucoup de code, je suis habitué à faire:

using (NorthWindEntities db = new NorthWindEntities() { 
} 

Dans chaque méthode unique qui a besoin d'une connexion, et si cette méthode appelle d'autres qui aurai besoin, ça va passer db comme un paramètre pour eux. C'est ainsi que j'ai tout fait avec mes objets de connexion avant que Linq-to-SQL existe.

L'autre chose qui me rend mal à l'aise est que NorthWindEntities implémente IDisposable, ce qui par convention signifie que je devrais appeler sa méthode Dispose(), et je ne le suis pas.

Que pensez-vous de cela?
Est-il correct d'utiliser l'objet Entités comme je le fais? Devrait-il prendre soin de ses connexions en les ouvrant et les fermant pour chaque requête?
Ou devrais-je le mettre explicitement avec une clause using()?

Merci!

Répondre

21

Le contrôleur lui-même implémente IDisposable. Vous pouvez donc remplacer Dispose et éliminer tout ce qui est (comme un contexte d'objet) initialisé lorsque le contrôleur est instancié.

Le contrôleur ne vit que jusqu'à une seule requête. Donc avoir une utilisation dans une action et avoir un contexte d'objet pour tout le contrôleur est exactement le même nombre de contextes: 1.

La grande différence entre ces deux méthodes est que l'action sera terminée avant que la vue ne soit rendue. Donc, si vous créez votre ObjectContext dans une instruction using à l'intérieur de l'action, ObjectContext aura été éliminé avant que la vue ne soit rendue. Donc vous feriez mieux de lire quelque chose du contexte dont vous avez besoin avant la fin de l'action. Si le modèle que vous passez à la vue est une liste paresseuse comme un IQueryable, vous aurez disposé le contexte avant que la vue soit rendue, provoquant une exception lorsque la vue essaye d'énumérer le IQueryable. Par contre, si vous initialisez ObjectContext lorsque le Controller est initialisé (ou si vous écrivez un code d'initialisation paresseux qui l'initialise lorsque l'action est exécutée) et que vous disposez du ObjectContext dans Controller.Dispose, le contexte sera toujours être autour quand la vue est rendue. Dans ce cas, il est prudent de passer un IQueryable à la vue. Le contrôleur sera éliminé peu après le rendu de la vue.

Enfin, je m'en voudrais de ne pas souligner que c'est probablement une mauvaise idée de faire en sorte que votre contrôleur soit au courant de l'Entity Framework. Examinez l'utilisation d'un assemblage distinct pour votre modèle et le modèle de référentiel pour que le contrôleur communique avec le modèle. Une recherche Google va apparaître un peu à ce sujet.

+0

Ok, c'est logique. Maintenant, la question est ... Est-ce que je fais des choses incorrectement? Ai-je vraiment besoin de disposer de l'objet Entités? Que se passe-t-il si je ne le fais pas? Vais-je être "fuite" des connexions à SQL Server? –

+1

ObjectContext.Dispose ne fait pas beaucoup (voir Réflecteur). Mais il est raisonnable de présumer que cela pourrait changer et que vous * devriez * l'éliminer. –

3

Vous faites un bon point ici.Combien de temps l'ObjectContext doit-il fonctionner? Tous les modèles et les livres de pratiques (comme Microsoft-NET-Architecting-Applications de Dino Esposito) vous indiquent qu'un DataContext ne doit pas être long et ne doit pas être mis en cache. Je me demandais juste pourquoi ne pas avoir, dans votre cas, une classe ControllerBase (je ne suis pas au courant de l'implémentation de MVC, donc supporter avec moi) où ObjectContext est initié une fois pour tout le contrôleur. Pensez particulièrement au Identity Map Pattern, déjà implémenté par Entity Framework. Même si vous devez appeler un autre contrôleur en tant que PostsController, il fonctionnera toujours avec le même contexte et améliorera également les performances.