Występuje problem z kodem Entity Framework - pierwszy w MVC3. Wybieram ten wyjątek:Entity Framework Code-First: "ObjectStateManager nie może śledzić wielu obiektów za pomocą tego samego klucza."
Obiekt o tym samym kluczu już istnieje w ObjectStateManager. ObjectStateManager nie może śledzić wielu obiektów za pomocą tego samego klucza .
Jest to adresowane wiele razy na SO, ale mam problem z wykorzystaniem któregokolwiek z sugerowanych rozwiązań w mojej sytuacji.
Oto przykładowy kod:
FestORM.SaleMethod method = new FestORM.SaleMethod
{
Id = 2,
Name = "Test Sale Method"
};
FestContext context = new FestContext();
//everything works without this line:
string thisQueryWillMessThingsUp =
context.SaleMethods.Where(m => m.Id == 2).Single().Name;
context.Entry(method).State = System.Data.EntityState.Modified;
context.SaveChanges();
edytowane wyjaśnienia: Ja próbuje zaktualizować obiekt, który już istnieje w bazie danych.
Wszystko działa poprawnie bez zapytania zanotowanego w kodzie. W mojej aplikacji mój kontroler tworzy instancję kontekstu i ten sam kontekst jest przekazywany do kilku repozytoriów, które są używane przez kontroler - więc nie jestem w stanie po prostu użyć innego kontekstu do początkowej operacji zapytania. Próbowałem usunąć obiekt, który nie był śledzony w ObjectStateManager, ale nie mogę się z tym nigdzie dostać. Próbuję znaleźć rozwiązanie, które będzie działać dla obu warunków: czasami będę aktualizować obiekt, który jest śledzony przez ObjectStateManager, a czasem stanie się, że nie został jeszcze śledzony.
FWIW, moi prawdziwi funkcje repozytorium wyglądać tak, jak na powyższym kodzie:
public void Update(T entity)
{
//works ONLY when entity is not tracked by ObjectStateManager
_context.Entry(entity).State = System.Data.EntityState.Modified;
}
public void SaveChanges()
{
_context.SaveChanges();
}
Jakieś pomysły? Walczyłem to zbyt długo ...
Dzięki. (Nie pozwól mi zagłosować na twoją odpowiedź, ponieważ jestem nowy.) Problem polega na tym, że nie wiem, kiedy robię zapytanie poprzedzające przyszłą aktualizację. Zapytanie może zostać zakopane gdzieś w warstwie usług, a następnie, gdy przejdę do aktualizacji tego samego obiektu, który był zapytany, trafię w błąd. Czy istnieje sposób, w jaki mogę usunąć obiekt ze śledzenia kontekstowego, lub uzyskać odbicie obiektu śledzonego przez kontekst i przekazać do kontekstu, że rzeczywiście aktualizuję ten jeden przedmiot? Zbadałem niektórych w tym kierunku, ale bez powodzenia. – Josh
To zależy od zamiaru zapytania. Jeśli zapytanie ma na celu przeniesienie encji do kontekstu, aby można było je aktualizować i zapisywać, co jest normalne, należy to zaprojektować, prawdopodobnie upewniając się przed zapisaniem, że podmiot został wniesiony, a jeśli nie już wcześniej sprowadzono. Jeśli intencją zapytania jest uzyskanie pewnej własności obiektu z bazy danych z jakiegoś powodu bez doprowadzenia encji do kontekstu, użyj AsNoTracking w tym zapytaniu, jak pokazano powyżej. –
Aby dodać do poprzedniego komentarza, jeśli chcesz upewnić się, że obiekt został wprowadzony, użyj metody Znajdź przed aktualizacją właściwości w encji i zapisaniem. Możesz również użyć zapytania zamiast Znajdź - domyślnie zapytanie wywoła tylko encję, jeśli nie jest już w kontekście. Ale Find jest bardziej wydajny. –