Próbuję zapisać dane pracownika, które mają odniesienia do miasta. Ale za każdym razem, gdy próbuję zapisać kontakt, który jest sprawdzany, pojawia się wyjątek „ADO.Net Entity Framework Do obiektu jednostki nie można odwoływać się w wielu wystąpieniach IEntityChangeTracker”
Przeczytałem tak wiele postów, ale nadal nie mam pojęcia, co robić ... mój kod kliknięcia przycisku Zapisz znajduje się poniżej
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);
}
i Kodeks obsługi pracowników
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";
}
Form
(co zawsze reprezentuje tylko jedną jednostkę pracy) naThread
(ponieważDbContext
nie ma gwarancji, że będzie bezpieczny wątkowo).Kroki do reprodukcji można uprościć do tego:
Kod bez błędów:
Użycie tylko jednego
EntityContext
może rozwiązać ten problem. Zapoznaj się z innymi odpowiedziami, aby uzyskać inne rozwiązania.źródło
To jest stary wątek, ale innym rozwiązaniem, które wolę, jest po prostu zaktualizowanie cityId i nie przypisywanie modelu otworu City do Employee ... aby to zrobić Pracownik powinien wyglądać następująco:
Wtedy wystarczy przypisać:
źródło
Alternatywnie do wtrysku i jeszcze gorzej Singletona możesz zadzwonić do Detach metodę przed Add.
EntityFramework 6:
((IObjectContextAdapter)cs).ObjectContext.Detach(city1);
EntityFramework 4:
cs.Detach(city1);
Jest jeszcze jeden sposób, na wypadek gdybyś nie potrzebował pierwszego obiektu DBContext. Po prostu opakuj go za pomocą słowa kluczowego:
źródło
dbContext1.Entry(backgroundReport).State = System.Data.Entity.EntityState.Detached
'aby odłączyć, a następnie mogłem użyćdbContext2.Entry(backgroundReport).State = System.Data.Entity.EntityState.Modified;
do aktualizacji. Pracował jak senMiałem ten sam problem, ale mój problem z rozwiązaniem @ Slauma (chociaż w niektórych przypadkach świetny) polega na tym, że zaleca ono przekazanie kontekstu do usługi, co oznacza, że kontekst jest dostępny z mojego kontrolera. Wymusza również ścisłe powiązanie między moim kontrolerem a warstwami usług.
Używam Dependency Injection, aby wstrzyknąć warstwy usługi / repozytorium do kontrolera i jako takie nie mam dostępu do kontekstu z kontrolera.
Moje rozwiązanie polegało na tym, aby warstwy usług / repozytorium korzystały z tego samego wystąpienia kontekstu - Singleton.
Klasa pojedyncza kontekstu:
Źródła: http://msdn.microsoft.com/en-us/library/ff650316.aspx
i http://csharpindepth.com/Articles/General/Singleton.aspx
Klasa repozytorium:
Istnieją inne rozwiązania, takie jak jednokrotne utworzenie wystąpienia kontekstu i przekazanie go do konstruktorów warstw usługi / repozytorium lub innego, o którym czytałem, który implementuje wzorzec jednostki pracy. Jestem pewien, że jest więcej ...
źródło
W moim przypadku korzystałem z platformy ASP.NET Identity Framework. Użyłem wbudowanej
UserManager.FindByNameAsync
metody, aby pobraćApplicationUser
jednostkę. Następnie próbowałem odwołać się do tej jednostki na nowo utworzonej jednostce na innejDbContext
. Spowodowało to wyjątek, który pierwotnie widziałeś.Rozwiązałem to, tworząc nową
ApplicationUser
jednostkę z tylko metodąId
from theUserManager
i odwołując się do tej nowej jednostki.źródło
Miałem ten sam problem i mogłem rozwiązać tworzenie nowej instancji obiektu, który próbowałem zaktualizować. Następnie przekazałem ten obiekt do mojego repozytorium.
źródło
W tym przypadku okazuje się, że błąd jest bardzo wyraźny: Entity Framework nie może śledzić jednostki przy użyciu wielu wystąpień
IEntityChangeTracker
lub zazwyczaj wielu wystąpieńDbContext
. Rozwiązania są następujące: użyj jednej instancjiDbContext
; dostęp do wszystkich potrzebnych jednostek za pośrednictwem jednego repozytorium (w zależności od jednego wystąpieniaDbContext
); lub wyłączając śledzenie dla wszystkich jednostek, do których uzyskano dostęp za pośrednictwem repozytorium innego niż to, które zgłasza ten szczególny wyjątek.Po odwróceniu wzorca sterowania w .Net Core Web API często stwierdzam, że mam kontrolery z zależnościami, takimi jak:
i sposób użycia
Ponieważ wszystkie trzy repozytoria zależą od różnych
DbContext
instancji na żądanie, mam dwie możliwości uniknięcia problemu i utrzymania oddzielnych repozytoriów: zmień iniekcję DbContext, aby utworzyć nową instancję tylko raz na wywołanie:lub, jeśli jednostka podrzędna jest używana tylko do odczytu, wyłączenie śledzenia w tej instancji:
źródło
Użyj tego samego obiektu DBContext w całej transakcji.
źródło
Trafiłem na ten sam problem po wdrożeniu IoC dla projektu (ASP.Net MVC EF6.2).
Zwykle inicjowałbym kontekst danych w konstruktorze kontrolera i używałbym tego samego kontekstu do inicjalizacji wszystkich moich repozytoriów.
Jednak użycie IoC do utworzenia instancji repozytoriów spowodowało, że wszystkie miały oddzielne konteksty i zacząłem otrzymywać ten błąd.
Na razie wróciłem do tworzenia nowych repozytoriów ze wspólnym kontekstem, podczas gdy myślę o lepszym sposobie.
źródło
Tak właśnie napotkałem ten problem. Najpierw muszę zapisać mój,
Order
który wymaga odniesienia do mojejApplicationUser
tabeli:Problem polega na tym, że inicjuję nowy ApplicationDbContext, aby zapisać moją nową
Order
jednostkę:Aby rozwiązać problem, użyłem tego samego ApplicationDbContext zamiast korzystania z wbudowanego UserManagera w ASP.NET MVC.
Zamiast tego:
Użyłem mojej istniejącej instancji ApplicationDbContext:
źródło
Źródło błędu:
Mam nadzieję, że ktoś zaoszczędzi trochę cennego czasu
źródło