2010-12-06 39 views
0

J'ai une relation many-to-many Patients - PatientDevices - Dispositifs et un modèle edmx de base (pas de poco, génération automatique). PatientDevices est généré en tant qu'entité, car il contient plus de colonnes que les clés étrangères.Comment mettre à jour un second ObjectContext avec des suppressions effectuées sur le premier

Lorsque je crée deux ObjectContexts et que j'ajoute un nouveau PatientDevice dans le premier, le second l'a également. Lors de la suppression de cette relation de la première, il est encore dans le second contexte:

var entities1 = new TherapyDatabaseDevEntities(); 
var entities2 = new TherapyDatabaseDevEntities(); 

entities1.PatientDevices.AddObject(new PatientDevice 
{ 
    Patient = entities1.Patients.First(), 
    Device = entities1.Devices.First() 
}); 
entities1.SaveChanges(); 

var relation1a = entities1.Patients.First().PatientDevices.ToList(); 
var relation2a = entities2.Patients.First().PatientDevices.ToList(); 

entities1.PatientDevices.DeleteObject(entities1.PatientDevices.ToList().Last()); 
entities1.SaveChanges(); 

var relation1b = entities1.Patients.First().PatientDevices.ToList(); 
var relation2b = entities2.Patients.First().PatientDevices.ToList(); 

relation1a et relation2a ont tous deux une entrée. relation1b n'a pas d'entrée, mais relation2b a une entrée. Même si vous travaillez avec avant que la requête rafraîchit:

entities2.Refresh(RefreshMode.StoreWins, entities2.Patients); 
entities2.Refresh(RefreshMode.StoreWins, entities2.PatientDevices); 
entities2.Refresh(RefreshMode.StoreWins, entities2.Devices); 
var relation1b = entities1.Patients.First().PatientDevices.ToList(); 
// still 1 entry 
var relation2b = entities2.Patients.First().PatientDevices.ToList(); 

Est-il possible d'amener le second contexte à jour ou dois-je créer un autre ObjectContext?

Modifier

Je trouve que si je fais ceci:

entities2.Refresh(RefreshMode.StoreWins, entities2.Patients.First().PatientDevices); 

la relation est mis à jour correctement. Il est dommage que sans l'actualisation entity2.PatientDevices ne contienne plus l'objet supprimé, mais entities2.Patients.First(). PatientDevices l'a toujours.

Est-ce un comportement prévu?

+0

Pourquoi avez-vous besoin de deux contextes en même temps? C'est très inhabituel. – Steven

+0

Nous avons une application de bureau qui répertorie les appareils dans un contrôle de liste (premier contexte) et les onglets patient où vous pouvez attacher un appareil à un patient (deuxième contexte). Nous avons différents contextes pour annuler les modifications apportées à un patient (bouton d'annulation) ==> unité de motif de travail. –

+0

Le motif Unité de travail est utilisé pour conserver les modifications dans * dépôts multiples *, et non * contextes multiples *. Vous pouvez presque penser à 2 contextes comme 2 bases de données différentes (hypothétiquement bien entendu - puisque EF assumera 2 contextes comme éventuellement 2 serveurs différents). Steven a raison, ce que vous faites est très inhabituel - vous devriez exposer les entites dans votre contexte via des dépôts et utiliser UoW ​​pour gérer ces dépôts. Un seul contexte est requis. Pourquoi avez-vous besoin de différents contextes pour "annuler les changements". Utilisez la restauration sur votre périmètre de transaction/UoW. – RPM1984

Répondre

0

Si vous devez avoir plusieurs contextes et travailler directement avec vos entités, jetez un oeil aux méthodes Attacher et Détacher, qui, comme les noms suggérés, sont utilisés pour associer/dissocier un objet du contexte d'où il provient. Notez cependant que ces méthodes ne font que dissocier l'objet que vous transmettez en tant qu'argument, et non les objets associés, de sorte que vous devrez probablement parcourir les objets connectés en les séparant, ce qui est désordonné. Ma préférence serait d'utiliser viewmodels de sorte que vous ne modifiez pas les entités directement, mais les représentations de celles-ci. Lorsqu'un utilisateur enregistre explicitement un objet, récupérez cet objet et mettez à jour les modifications de cet objet uniquement sur un nouveau contexte.

var entities1 = new TherapyDatabaseDevEntities(); 
var patient1 = entities1.Patients.Single(p => p.Id = 12345); 

... de votre contexte disposer, il est plus nécessaire, et apportez vos modifications ici

var entities2 = new TherapyDatabaseDevEntities(); 
var patient2 = entities2.Patients.Single(p => p.Id = 12345); 

patient2.Property1 = patient1.Property1; 

... mise à jour avec d'autres changements (il y a des façons de rendre ce code plus propre, juste montrer exemple le plus simple)

entities2.SaveChanges(); 
entities2.Dispose(); 

Certains de documents de référence sur Attacher/Détacher ici - http://msdn.microsoft.com/en-us/library/bb896271.aspx

Faites une recherche sur le contexte de cadre d'entité liftimes, il y a beaucoup de discussion sur ce sujet qui pourrait vous aider à décider d'un itinéraire qui correspond à vos besoins.

+0

J'ai lu à propos de la durée de vie du contexte et j'accepte (http://blogs.microsoft.co.il/blogs/gilf/archive/2010/02/07/entity-framework-context-lifetime-best-practices.aspx) estime que pour les applications WPF, un contexte par formulaire est le meilleur. Je ne pense pas que détacher/attacher ou un emballage est une bonne solution. Qu'en est-il des relations modifiées? Vous devez détacher/attacher (ou mettre à jour via un wrapper) ces entités aussi. Cela pourrait devenir lourd ou vous ai-je mal compris? –

+0

Non, vous êtes sur, c'est lourd. J'ai rencontré le même problème, et je n'ai pas encore trouvé une meilleure alternative, d'où la moins mauvaise option que j'ai trouvée. Vous pouvez récupérer les données sans suivi de modification (MergeOptions ou quelque chose comme ça, sur le contexte), mais vous devez toujours attacher quand vous allez enregistrer (avec des éléments enfants). J'ai écrit quelques méthodes d'extension génériques pour faire ma mise à jour, ce qui rend beaucoup plus propre. – RichardW1001

+0

Aussi juste remarqué que vous avez dit que vous utilisez les objets par défaut. Avez-vous envisagé d'utiliser le générateur POCO ou Self-Tracking? J'utilise POCO avec un gabarit T4 légèrement personnalisé, je n'ai aucune expérience de l'autoguidage quoiqu'il en soit mais il vaut le coup d'oeil, peut-être que quelqu'un qui en sait plus sur Self-Tracking trouvera cela et prêtera ses pensées. – RichardW1001