2009-08-09 7 views
3

Je suis nouveau dans Entities Framework, et je commence juste à jouer avec ça dans mon temps libre. L'une de mes principales questions concerne la gestion des ObjectContexts.ObjectContext réutilisable ou nouveau ObjectContext pour chaque ensemble d'opérations?

qui est généralement préféré/recommandé de ceux-ci:

Ce

public class DataAccess{ 

    MyDbContext m_Context; 

    public DataAccess(){ 
     m_Context = new MyDbContext();   
    } 

    public IEnumerable<SomeItem> GetSomeItems(){ 
     return m_Context.SomeItems; 
    } 

    public void DeleteSomeItem(SomeItem item){ 
     m_Context.DeleteObject(item); 
     m_Context.SaveChanges(); 
    } 
} 

Ou cela?

public class DataAccess{ 

    public DataAccess(){ } 

    public IEnumerable<SomeItem> GetSomeItems(){ 
     MyDbContext context = new DbContext(); 
     return context.SomeItems; 
    } 

    public void DeleteSomeItem(SomeItem item){ 
     MyDbContext context = new DbContext(); 
     context.DeleteObject(item); 
     context.SaveChanges(); 
    } 
} 
+0

Assez lié à http://stackoverflow.com/questions/1072391/with-linq-do-you-create-a-single-dbcontext-per-request-like-nhibernate-requires – shahkalpesh

+0

Et cela ... http : //stackoverflow.com/questions/226127/ Bien que la discussion soit Linq2Sql, la même chose s'applique. – spender

Répondre

6

ObjectContext est censé être la "unité de travail". Essentiellement, cela signifie que pour chaque «opération» (par exemple: chaque requête de page Web), il devrait y avoir une nouvelle instance ObjectContext. Dans cette opération, le même objet ObjectContext doit être réutilisé.

Cela a du sens lorsque vous y réfléchissez, car les transactions et la soumission de modifications sont toutes liées à l'instance ObjectContext. Si vous n'écrivez pas une application Web et que vous écrivez à la place une application WPF ou Windows Forms, cela devient un peu plus complexe, car vous n'avez pas la portée "requête" stricte d'une page Web. -load vous donne, mais vous avez l'idée. PS: Dans l'un ou l'autre de vos exemples, la durée de vie de ObjectContext sera soit globale, soit transitoire.Dans les deux cas, il ne doit PAS être dans la classe DataAccess - il doit être transmis en tant que dépendance

0

Juste un petit mot - les deux morceaux de code sont à peu près les mêmes dans leur problème sous-jacent. C'est quelque chose que j'ai regardé, parce que vous ne voulez pas continuer à ouvrir et fermer le contexte (voir le deuxième exemple) en même temps, vous n'êtes pas sûr si vous pouvez faire confiance à Microsoft pour disposer correctement du contexte pour vous. L'une des choses que j'ai faites a été de créer une classe de base commune paresseuse qui charge le Context et implémente le destructeur de classe de base pour disposer des choses. Cela fonctionne bien pour quelque chose comme le framework MVC, mais conduit malheureusement au problème de devoir passer le contexte autour des différentes couches pour que les objets métier puissent partager l'appel.

En fin de compte je suis allé avec quelque chose en utilisant Ninject pour injecter cette dépendance dans chaque couche et l'avait utilisation répertorient

+0

Microsoft recommande de ne pas avoir DataContexts ou ObjectContexts à long terme. Il tue les performances et complique le suivi des objets. –

1

Si vous gardez le même contexte d'un processus de longue durée en cours d'exécution beaucoup interroge contre , linq-to-sql (je n'ai pas testé linq pour les entités, mais je suppose que c'est le même problème) devient très lent (1 requête par seconde après quelques 1000 requêtes simples). Renouveler le contexte régulièrement résout ce problème et ne coûte pas trop cher. Qu'est-ce qui se passe, c'est que le contexte garde une trace de chaque requête que vous faites sur lui, donc si elle n'est pas réinitialisée d'une certaine façon, elle devient vraiment grosse ... Autre problème est alors la mémoire qu'il faut.

Cela dépend principalement de la façon dont votre application fonctionne, et si vous créez une instance DataAccess régulièrement ou si vous la gardez toujours la même. J'espère que cela aide.

Stéphane

0

Bien que je ne sois pas en faveur de toujours créer, ce qui doit être, des objets compliqués chaque fois que j'en ai besoin - moi aussi ont trouvé que les DataContexts de Linq à Sql et les ObjectContexts de EF sont mieux créés si nécessaire. Ces deux méthodes effectuent beaucoup d'initialisation statique en fonction du modèle sur lequel vous les exécutez, qui est mis en cache pour les appels suivants. Vous constaterez donc que le démarrage initial d'un contexte sera plus long que toutes les instanciations suivantes. Le plus gros obstacle auquel vous êtes confronté est le fait qu'une fois que vous obtenez une entité du contexte, vous ne pouvez pas simplement la renvoyer dans une autre pour effectuer des opérations de mise à jour ou y ajouter des entités reliées. Dans EF vous pouvez rattachez une entité à un nouveau contexte. En L2S, ce processus est presque impossible.

+0

à la suite de cela - J'ai toujours simplement une instruction using autour de mon datacontext/objectcontext, et j'y pousse toute manipulation de données; Mes contextes sont toujours aussi éphémères que possible. –

Questions connexes