2013-12-18 12 views

Odpowiedz

9

Co to słabo udokumentowane błąd próbuje powiedzieć to to, że przypadkowo skonfigurować system, w którym śledzenie zmian powoduje więcej zmian.

Gdy Entity Framework zmienił właściwość w jednej z twoich jednostek, na przykład podczas SaveChanges z aktualizacjami ID identyfikatora, uruchomiłeś kod, który zmienił inne śledzone właściwości.

Na przykład właściwość, że Entity Framework zachodziło wywołał zdarzenie, może INotifyPropertyChanged, który być może został subskrybowany przez BindingSource lub jakiejś listy wiązania, którego ListChanged event handler był w interfejsie i wywołał obliczenie jakiegoś innego mienia , a moduł do śledzenia zmian wykrył drugą zmianę właściwości.

Prosta diagnoza polega na umieszczeniu punktu przerwania w wywołaniu SaveChanges() i zaraz po wywołaniu funkcji SaveChanges(). Po trafieniu pierwszego punktu przerwania umieść punkt przerwania na każdej procedurze obsługi zdarzeń, która może zostać uruchomiona. (BindingSources są znane ze zwielokrotnienia wydarzeń.) Kontynuuj debugowanie. Jeśli którykolwiek punkt przełomowy zostanie trafiony inaczej niż punkt następujący bezpośrednio po SaveChanges, wiesz, gdzie jest problem.

Proste rozwiązanie polega na ustawieniu flagi, na przykład IsSaving, po każdej stronie wywołania SaveChanges. Następnie w każdym niewłaściwie działającym programie obsługi zdarzeń, wykonaj prostą kontrolę i nie modyfikuj żadnych encji, jeśli DbContext jest w trakcie zapisywania. Upewnij się, że używasz finally w przypadku SaveChanges zgłasza wyjątek, że złapać na wyższym poziomie:

IsSaving = true; 
try 
{ 
    await db.SaveChangesAsync() 
} 
finally 
{ 
    IsSaving = false; 
} 

(Inną możliwością jest to, że zostały zmieniania podmiotu z wielu wątków — nigdy wiązać trackera zmiana w wielokrotności wątki!)

+0

Piękne wyjaśnienie, dziękuję bardzo! – Dan

+0

Dziękujemy za przesłanie zarówno pytania, jak i szczegółowej odpowiedzi! – Hannish

1

Miałem dokładnie ten sam problem. Podłączyłem się do zdarzenia INotifyPropertyChanged, które stworzyło możliwość zmiany właściwości podczas wywołania SaveChanges(). Myślę, że lepiej jest odłączyć funkcje obsługi zdarzeń od śledzonych encji podczas wykonywania dbContext.SaveChanges(), Remove().

+0

Nieużywanie często stanowi najbezpieczniejszą i najlżejszą alternatywę. Jednak dla nas istnieje przypadek, w którym warto być powiadamianym o zmianie, nawet jeśli nie ustawiamy właściwości Entity Framework-visible w tym czasie. – jnm2

2

Wyjaśnię moje doświadczenia z tym błędem, mając nadzieję, że może to komuś pomóc. I dzięki jnm2 za piękne wyjaśnienie.

miałem faktury i otrzymania podmiotów oraz InvoiceViewModel. Thie ViewModel zasubskrybowano właściwość Faktura zmieniona, wewnątrz której gromadzono zdarzenia CanExecuteChanged.

dodałem Otrzymanie faktury właściwość nawigacji i nazwał SaveChanges(), dzięki czemu poziom Invoice.ReceiptID własności zmieniło i wyzwalanych OnPropertyChanged obsługi zdarzeń na ViewModel, który z kolei podniesioną wszelkiego rodzaju imprez CanExecuteChanged.

Problem było, że jeden z puszki nazwa_polecenia Execute metody dzwoni Context.ChangeTracker.HasChanges() które ostatecznie zwrócił wyjątek.

Jak to naprawiłem? Podążałem za jnm2, oznaczyłem maszynę wirtualną za pomocą IsSaving i zaznaczono flagę wewnątrz programu obsługi zdarzeń OnPropertyChanged.

Jeszcze raz dziękuję jnm2 i mam nadzieję, że ktoś również uzna to za pomocne.

Powiązane problemy