7

Ich arbeite seit Monaten an meiner ASP.NET MVC-Anwendung. Als ich anfing, daran zu arbeiten, benutzte ich Entity Framework 4.3 (Code-First w/Migrations). Während ich dies tat, stieß ich auf einige Probleme, die versuchen, Aktualisierungen auf meiner MainClient-Tabelle vorzunehmen. Der MainClient enthält alle grundlegenden Informationen eines Kunden und hat eine 1: 1-Beziehung mit der Tabelle BPClient, die spezifischere Informationen über diesen Kunden enthält, die zu seiner Lizenzvereinbarung für das BP-Modul gehören. Beide können auf der gleichen Seite in einem Tab-Steuerelement bearbeitet werden. Allerdings hielt ich auf die folgende Ausnahme, wenn ich versuche, um die EntityState des MainClient Objekts zu ändern EntityState.Modified werden:Entity Framework 4.3 vs. 5.0 Aktualisieren der Unterschiede

System.InvalidOperationException : An object with the same key already exists 
in the ObjectStateManager. The ObjectStateManager cannot track multiple objects 
with the same key. 

ich beim Debuggen bemerkt, dass das Objekt selbst wurde Frei stehend betrachtet, wenn es in meine Controller-Klasse ging gespeichert werden. Um dieses Problem zu umgehen, habe ich eine ähnliche Lösung für die Probleme gefunden, die in this blog post und in this SO question gefunden wurden. Hier ist, wie der Code für Wiederanbringung der Objekte sah danach (unordentlich, ich weiß), da die Edit-Methode in einem MainClient Objekt client genannt geben wird:

var newClientObject = new MainClient { ClientID = client.ClientID }; 
Db.MainClients.Attach(newClientObject); 
Db.Entry(newClientObject).CurrentValues.SetValues(client); 

var bpClient = new BPClient { ClientID = client.ClientID, BaseClient = newClientObject }; 
if (client.BPClient != null) 
{ 
    Db.BostonpostClients.Attach(bpClient); 
    Db.Entry(bpClient).CurrentValues.SetValues(client.BPClient); 
} 

Db.SaveChanges() 

Dies funktionierte gut und gut über alle Testfälle. Bis vor kurzem.

Vor kurzem habe ich meine Anwendung aktualisiert, um Entity Framework 5 zu verwenden (immer noch mit Code-First). Als ich die MainClient-Bearbeitungsseite erneut getestet habe, habe ich jedoch ein ziemlich unberechenbares Verhalten festgestellt. Einige Felder wurden beim Bearbeiten ohne Probleme gespeichert. Andere würden niemals der DB verpflichtet werden. Wieder andere würden in Ordnung bleiben, aber nur, wenn sie der einzige Teil des zu bearbeitenden Objekts wären. Ich habe den DbContext aus der Controller-Klasse ausgepackt und festgestellt, dass nicht nur die Änderungen auf der Seite an die Controller-Klasse gesendet wurden, sondern dass der ObjectStateManager sowohl das MainClient- als auch das BPClient-Objekt enthielt es mit den Änderungen, die auf der Seite auch gemacht worden waren! Ich sollte hier übrigens erwähnen, dass ich beim Debuggen keinen Fehler erhalten habe, auch nicht nach SaveChanges().

ich den Code zu versuchen beschlossen und zurückkommen, was es ursprünglich war, das ist den logischen Weg, es zu sagen, zu tun:

Db.Entry<BPClient>(client.BPClient).State = EntityState.Modified; 
Db.Entry<MainClient>(client).State = EntityState.Modified; 

Db.SaveChanges(); 

Und es funktioniert jetzt völlig in Ordnung. Keine InvalidOperationException. Das wurde also gut gelöst.

Was mich immer noch stört ist zu versuchen, herauszufinden, was in 5.0 geändert wurde, das meine frühere Reparatur aufhört zu arbeiten und alle wackelig auf mich zu gehen. Warum funktioniert dieser Code in 4.3, aber nicht in 5.0? Was in 5.0 hat die Datenbank mit diesem Code so unberechenbar gemacht?

Weiß jemand, warum das passiert wäre?

+0

Es könnte Ihnen helfen. Entity Framework 5 Enums und Moving Solution von EF 4.3 http://thedatafarm.com/blog/data-access/video-entity-framework-5-enums-and-moving-solution-from-ef-4-3/ – Aru

Antwort

0

Ich hatte dieses Problem selbst. Ich verwendete IDbSet-Klassen, um Datenbanktabellen zu füllen, was ich fand, als ich eine Eigenschaft virtuell machte EF5 führt eine Lazy-Ladung durch (meine virtuellen Eigenschaften wo andere Objekte in der Datenbank). Das bedeutet, dass ich einen neuen Primärschlüssel für die virtuelle Eigenschaft erhalte. Nun, wenn ich keine spezifische ID habe, die mit dem Objekt verknüpft ist, auf das ich verweisen möchte, versucht EF 5, eine Zwei-Wege-Beziehung herzustellen. Wenn Sie EF nicht ausdrücklich mitteilen, welcher Eigenschaft im DBContext zugeordnet werden soll, werden zwei Fremdschlüssel für dasselbe Objekt eingerichtet, was nicht zulässig ist. Hoffe das hilft.

+0

Danke um zu versuchen, meine Frage zu beantworten. Ich denke nicht, dass dies hier der Fall ist.Ich habe das 1: 1 zwischen MainClient und BPClient bereits als eine Zwei-Wege-Beziehung eingerichtet (sowohl mit virtuellen Eigenschaften als auch mit IDs). Ich versuche nur herauszufinden, warum der Code plötzlich nicht mehr funktioniert. – IronMan84

+0

mit nur virutal Eigenschaften verursacht Lazy Loading, haben Sie die gleiche Karte in Ihrem dbcontext zwischen den Eigenschaften getan? – Robert

+0

Ich verwende Data Annotation, nicht die FLuent API. Das Mapping ist vollständig auf dem Objekt selbst, nicht im DbContext. Ist etwas zwischen 4.3 und 5.0 in Bezug auf Lazy Loading passiert, das den Code auf diese Weise beeinflusst hätte? – IronMan84