entity-Objekt verwiesen werden kann, indem mehrere Instanzen von IEntityChangeTracker. beim hinzufügen Verwandte Objekte zu Entitäten im Entity Framework 4.1
Ich versuche zu sparen, Mitarbeiter details, die Referenzen mit der Stadt. Aber jedesmal, wenn ich versuchen, zu speichern mein Kontakt, der überprüft wird, bekomme ich die exception "ADO.Net Entity Framework Ein entity-Objekt verwiesen werden kann, indem mehrere Instanzen von IEntityChangeTracker"
Hatte ich gelesen, so viele post, aber immer noch nicht die genaue Vorstellung von dem, was zu tun ist...
meine Schaltfläche Speichern, code ist unten angegeben
protected void Button1_Click(object sender, EventArgs e)
{
EmployeeService es = new EmployeeService();
CityService cs = new CityService();
DateTime dt = new DateTime(2008, 12, 12);
Payroll.Entities.Employee e1 = new Payroll.Entities.Employee();
Payroll.Entities.City city1 = cs.SelectCity(Convert.ToInt64(cmbCity.SelectedItem.Value));
e1.Name = "Archana";
e1.Title = "aaaa";
e1.BirthDate = dt;
e1.Gender = "F";
e1.HireDate = dt;
e1.MaritalStatus = "M";
e1.City = city1;
es.AddEmpoyee(e1,city1);
}
und Employeeservice-Code
public string AddEmpoyee(Payroll.Entities.Employee e1, Payroll.Entities.City c1)
{
Payroll_DAO1 payrollDAO = new Payroll_DAO1();
payrollDAO.AddToEmployee(e1); //Here I am getting Error..
payrollDAO.SaveChanges();
return "SUCCESS";
}
InformationsquelleAutor Smily | 2012-04-17
Du musst angemeldet sein, um einen Kommentar abzugeben.
Weil diese zwei Linien ...
... nicht nehmen, einen parameter im Konstruktor, denke ich, dass Sie einen Kontext schaffen, innerhalb der Klassen. Beim laden der
city1
......befestigen Sie die
city1
auf den Kontext, inCityService
. Später fügen Sie einecity1
als ein Verweis auf die neueEmployee
e1
und fügen Siee1
einschließlich dieser Verweis aufcity1
auf den Kontext, inEmployeeService
. Als Ergebnis haben Siecity1
an den beiden anderen Kontext das ist, was die Ausnahme beklagt.Sie können dieses Problem beheben, indem wir einen Kontext außerhalb der service-Klassen und-Injektion, und verwenden Sie es in beide Dienste:
Ihre service-Klassen sehen ein bisschen aus wie repositories, die verantwortlich sind für nur eine einzige Person geben. In solch einem Fall wird man immer Probleme haben, sobald die Beziehungen zwischen Entitäten beteiligt sind, wenn Sie getrennte Kontexte für die Dienstleistungen.
Können Sie auch erstellen Sie eine einzelne Dienstleistung, die zuständig ist für eine Reihe von eng verbundenen Einrichtungen, wie ein
EmployeeCityService
(die einen einzelnen Kontext) und delegieren den gesamten Vorgang in IhremButton1_Click
- Methode eine Methode, die von diesem service.Sieht aus wie das mein problem lösen wird, ich habe nur keine Idee, wie Sie schreiben, die neue context-Instanz 🙁
Abstraktion, ORM ist, wie wenn man mit gelben Lippenstift auf ein turd.
Ich sein könnte vermisste von etwas hier, aber in einigen ORMs (insbesondere Entity Framework) den Daten-Kontext sollte immer nur von kurzer Dauer. Die Einführung einer statischen oder re-Kontext verwendet wird, sieht eine ganze Reihe anderer Herausforderungen und Probleme.
es hängt von der Nutzung. In Web-Anwendungen, seine in der Regel eine hin-und Rückfahrkarte. In Desktop-Anwendungen, die Sie möglicherweise auch eine pro
Form
(was auch immer es gerade ist, stellt eine unit of work) proThread
(weilDbContext
ist nicht garantiert threadsicher).InformationsquelleAutor Slauma
Schritte zum reproduzieren kann vereinfacht werden zu:
Code ohne Fehler:
Wenn Sie brauchen, um zu tun smth like this, wahrscheinlichsten Sie tun dies in der falschen Art und Weise... ich schlage vor, mit einem Kontext.
Es gibt Fälle, wo würden Sie wollen, um eine andere Instanz, wie beim zeigen in eine andere Datenbank.
Dies ist eine nützliche Vereinfachung des Problems; aber es ist nicht eine wirkliche Antwort.
InformationsquelleAutor Pavel Shkleinik
Dies ist ein Alter thread, aber eine andere Lösung, die ich bevorzuge, ist, aktualisieren Sie einfach die cityId und nicht zuweisen das Loch, Modell, Stadt, Mitarbeiter,... zu tun, die Mitarbeiter sollten so Aussehen:
Dann ist es genug Zuordnung:
InformationsquelleAutor user3484623
Ich hatte das gleiche problem, aber mein Problem mit dem @Slauma Lösung (obwohl große in bestimmten Fällen) ist, dass es empfiehlt, gebe ich den Kontext, in dem Dienst, der impliziert, dass der Kontext von mein controller. Es zwingt auch die enge Kopplung zwischen meinem controller und service-Layer.
Ich bin mit Dependency Injection-das einschleusen des Dienstes/repository Ebenen in die Steuerung und als solche haben keinen Zugriff auf den Kontext, aus dem controller.
Meine Lösung war, den Dienst/repository Schichten mit derselben Instanz des context - Singleton.
Kontext Singleton-Klasse:
Referenz: http://msdn.microsoft.com/en-us/library/ff650316.aspx
und http://csharpindepth.com/Articles/General/Singleton.aspx
Repository-Klasse:
Andere Lösungen existieren, wie der Instanziierung des Kontext-einmal und übergeben es in die Konstruktoren von Ihrem service/repository-Schichten oder anderen, die ich gelesen über die Umsetzung der Einheit von Arbeit-Muster. Ich bin sicher, es gibt mehr...
Ein Rahmen sollte nicht offen bleiben, länger als nötig, mit einer Singleton-offen zu halten für immer, ist die Letzte Sache, die Sie tun möchten.
Ich habe gesehen, gute Implementierungen dieser pro Anfrage. Verwenden Sie das Static-Schlüsselwort ist falsch, aber wenn Sie diese Muster zu instanziieren, die der Kontext an den Anfang der Anforderung und entsorgen Sie Sie am Ende der Anfrage, wäre es eine legitime Lösung.
Das ist wirklich schlecht beraten. Wenn Sie mit DI (ich sehe nicht, das beweisen Sie hier?) dann sollten Sie lassen Sie Ihre DI-container verwalten das Kontext Leben und sollte es wohl auch sein pro-Anfrage.
Das ist SCHLECHT. SCHLECHT. SCHLECHT. SCHLECHT. SCHLECHT. Vor allem, wenn dies ist eine web-Anwendung, da statische Objekte werden gemeinsam von allen threads und Benutzer. Dies bedeutet, dass mehrere Benutzer gleichzeitig von Ihrer website stampfenden auf Ihre Daten Kontext, potentiell Korrumpierende, speichern von änderungen, die Sie nicht wollen, oder auch nur das erstellen einer zufälligen Abstürze. DbContexts sollte NIE geteilt werden, die auf mehrere threads. Dann gibt es das problem, dass die Statik nie zerstört, so dass es sitzen und halten mit mehr und mehr Speicher...
InformationsquelleAutor kmullings
Alternativ zur Injektion und noch schlimmer Singleton, können Sie rufen Sie Trennen Methode, bevor Sie Hinzufügen.
EntityFramework 6:
((IObjectContextAdapter)cs).ObjectContext.Detach(city1);
EntityFramework 4:
cs.Detach(city1);
Gibt es noch einen anderen Weg, in Fall müssen Sie nicht zuerst DBContext-Objekt. Nur wickeln Sie es mit mit Stichwort:
dbContext1.Entry(backgroundReport).State = System.Data.Entity.EntityState.Detached
' zu trennen und dann konntedbContext2.Entry(backgroundReport).State = System.Data.Entity.EntityState.Modified;
zu aktualisieren. Arbeitete wie ein TraumJa, Peter. Ich sollte erwähnen, mark-Zustand, wie Geändert.
In meiner Anwendung starten (global.asax) Logik, die ich war das laden einer Liste von widgets.. eine einfache Liste von Referenz-Objekten, die ich stash in den Speicher. Da ich dabei war meine EF-Rahmen innen Mit Aussagen, ich dachte es wäre kein Problem wenn es später bei meinem controller hab um die Zuweisung dieser Objekte in einer business-Grafik (hey, dieser alte Rahmen verschwunden ist, richtig?) - diese Antwort hat mich gerettet.
InformationsquelleAutor Roman O
In meinem Fall war ich mit dem ASP.NET Identitäts-Framework. Ich hatte mich für die eingebauten
UserManager.FindByNameAsync
- Methode zum abrufen einerApplicationUser
Einheit. Ich habe dann versucht, mit einem Verweis auf diesen Rechtsträger auf einen neu geschaffenen Rechtsträger auf einen anderenDbContext
. Dies führte zu der Ausnahme, die Sie ursprünglich sahen.Ich dies Problem gelöst, indem eine neue
ApplicationUser
Person nur mit derId
von derUserManager
Methode und verweisen auf die neue Entität.InformationsquelleAutor Justin Skiles
Ich hatte das gleiche problem und konnte ich lösen, indem eine neue Instanz von dem Objekt, das ich versuchte, zu Aktualisieren. Dann überholte ich das Objekt meiner reposotory.
InformationsquelleAutor karolanet333
In diesem Fall, es stellt sich heraus, der Fehler ist ganz klar: Entity Framework nicht verfolgen können, ein Unternehmen mit mehreren Instanzen von
IEntityChangeTracker
oder in der Regel mehrere Instanzen vonDbContext
. Die Lösungen sind: verwenden Sie eine Instanz vonDbContext
; Zugriff auf alle benötigten Entitäten durch ein einzelnes repository (abhängig von einer Instanz vonDbContext
); oder schalten Sie das tracking für alle Elemente zugegriffen, die über ein repository als die anderen werfen diese Besondere Ausnahme.Wenn nach einer inversion of control pattern .Net-Core-Web-API, die ich Häufig finde, dass ich Controller mit Abhängigkeiten wie:
- und Gebrauchsspuren wie
Da alle drei repositories abhängig von verschiedenen
DbContext
Instanzen pro Anfrage, habe ich zwei Möglichkeiten das problem zu vermeiden, und pflegen Sie separate Repositorys: ändern Sie die Injektion des DbContext zum erstellen einer neuen Instanz nur einmal pro Aufruf:oder, wenn die untergeordnete Einheit ist in einer nur-lese-Weise, ausschalten tracking für diese Instanz auf:
InformationsquelleAutor Kjata30
Verwenden Sie die gleichen DBContext-Objekt in der gesamten Transaktion.
InformationsquelleAutor Nalan Madheswaran
Fehler Quelle:
Hoffe, jemand spart einige wertvolle Zeit
InformationsquelleAutor Bourne Kolo