2010-12-06 6 views
0

Ich habe eine Viele-zu-viele-Beziehung Patienten - Patientengeräte - Geräte und ein grundlegendes edmx-Modell davon (keine poco, automatische Generierung). PatientDevices wird als Entität generiert, da es mehr Spalten als die Fremdschlüssel hat.Wie man einen zweiten ObjectContext mit Löschungen auf der ersten Ebene aktualisiert

Wenn ich zwei ObjectContexte erstellen und ein neues PatientDevice in das erste hinzufügen, hat das zweite auch das. Wenn diese Beziehung von dem ersten zu löschen, ist es immer noch in dem zweiten Kontext:

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 und relation2a beide einen Eintrag haben. relation1b hat keinen Eintrag, aber relation2b hat einen Eintrag. Auch wenn mit Auffrischungen vor der Abfrage arbeiten:

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(); 

Gibt es eine Möglichkeit, den zweiten Kontext zu bringen, auf dem Laufenden oder muss ich einen anderen Object schaffen?

bearbeiten

fand ich heraus, dass, wenn ich dies tun:

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

die Beziehung richtig aktualisiert wird. Es ist schade, dass ohne die Aktualisierung entities2.PatientDevices das gelöschte Objekt nicht mehr enthält, sondern entities2.Patients.First(). PatientDevices hat es immer noch.

Ist das beabsichtigte Verhalten?

+0

Warum benötigen Sie zwei Kontexte gleichzeitig? Das ist sehr ungewöhnlich. – Steven

+0

Wir haben eine Desktop-App, die Geräte in einem Listen-Steuerelement (erster Kontext) und Patienten-Tabs auflistet, wo Sie ein Gerät an einen Patienten anhängen können (zweiter Kontext). Wir haben verschiedene Kontexte, um Änderungen an einem Patienten rückgängig zu machen (Abbrechen-Taste) ==> Arbeitseinheitsmuster. –

+0

Das Muster der Arbeitseinheit wird verwendet, um Änderungen in * mehreren Repositorys *, nicht * mehreren Kontexten * persistent zu machen. Sie können fast 2 Kontexte als 2 verschiedene Datenbanken betrachten (hypothetisch natürlich - da EF 2 Kontexte als möglicherweise 2 verschiedene Server annehmen wird). Steven hat recht, was Sie tun, ist sehr ungewöhnlich - Sie sollten die Entdeckungen in Ihrem Kontext über Repositories aufdecken und UoW verwenden, um diese Repositories zu verwalten. Nur 1 Kontext ist erforderlich. Warum brauchen Sie unterschiedliche Kontexte, um "Änderungen rückgängig zu machen"? Verwenden Sie den Rollback für Ihren Transaktionsbereich/UoW. – RPM1984

Antwort

0

Wenn Sie mehrere Kontexte haben und direkt mit Ihren Entities arbeiten müssen, sehen Sie sich die Methoden Attach und Detach an, die ein Objekt aus dem Kontext assoziieren/dissoziieren, von dem es abgerufen wurde. Beachten Sie jedoch, dass diese Methoden nur das Objekt, das Sie als Argument übergeben, nicht assoziierte Objekte lösen, so dass Sie wahrscheinlich durch die verbundenen Objekte laufen müssen, die jedes einzelne trennen, was unordentlich ist.

Meine Präferenz wäre, Viewmodels zu verwenden, so dass Sie die Entitäten nicht direkt bearbeiten, sondern Repräsentationen von ihnen. Wenn ein Benutzer ein Objekt explizit speichert, rufen Sie dieses Objekt ab und aktualisieren Sie die Änderungen von diesem Objekt nur in einem neuen Kontext.

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

... von Ihrem Kontext verfügen, ist es nicht mehr erforderlich, und Ihre Änderungen vornehmen hier

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

patient2.Property1 = patient1.Property1; 

... Update mit anderen Änderungen (es gibt Möglichkeiten, diesen Code sauberer zu machen, nur zeigen einfachste Beispiel)

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

Einige Referenzmaterial auf Attach/hier abnehmen - http://msdn.microsoft.com/en-us/library/bb896271.aspx

Suchen Sie nach Kontextkontexten für Entitätsrahmen. Es gibt viele Diskussionen zu diesem Thema, die Ihnen bei der Entscheidung für eine Route helfen können, die Ihren Anforderungen entspricht.

+0

Ich habe über Kontextlebenszeiten gelesen und stimme dem zu (http://blogs.microsoft.co.il/blogs/gilf/archive/2010/02/07/entity-framework-context-lifetime-best-practices.aspx)) Meinung, dass für WPF-Apps ein Per-Form-Kontext am besten ist. Ich denke nicht, dass detach/attach oder ein Wrapper eine gute Lösung ist. Was ist mit veränderten Beziehungen? Sie müssen diese Entitäten ebenfalls trennen/anhängen (oder über einen Wrapper aktualisieren). Das könnte beschwerlich werden oder habe ich dich missverstanden? –

+0

Nein, Sie sind genau richtig, es ist umständlich. Ich habe das gleiche Problem und muss noch eine bessere Alternative sehen, daher gehe ich mit der am wenigsten schlechten Option, die ich gefunden habe. Sie könnten die Daten ohne Änderungsverfolgung abrufen (MergeOptions oder etwas Ähnliches für den Kontext), aber Sie müssen immer noch anhängen, wenn Sie zum Speichern gehen (mit untergeordneten Elementen). Ich habe einige generische Extension-Methoden geschrieben, um meine Aktualisierung durchzuführen, was es viel besser macht. – RichardW1001

+0

Sie haben gerade bemerkt, dass Sie die Standardobjekte verwenden. Haben Sie sich den POCO-Generator oder Self-Tracking angesehen? Ich benutze POCO mit einer leicht angepassten T4-Vorlage, aber ich habe keinerlei Erfahrung mit Selbst-Tracking, aber es wäre einen Blick wert, vielleicht findet jemand, der mehr über Self-Tracking weiß, dies und leiht ihm seine Gedanken. – RichardW1001

Verwandte Themen