Dzieje się tak, ponieważ DataAdapter
używa Optimistic Concurrency
domyślnie. Oznacza to, że jeśli próbujesz zaktualizować wiersz, który już nie istnieje w bazie danych lub został zmieniony, aktualizacja z DataAdapter
zawiedzie z powyższym wyjątkiem.
Możliwe scenariusze :
- Pomiędzy wybraniem danych do klienta i wysłaniem aktualizacji inny użytkownik usuwa lub aktualizuje ten wiersz ze swojej aplikacji.
- Może być tak, że usuwasz dane z innego miejsca w swojej aplikacji.
Na przykład :
- Wypełniasz
DataTable
które zostaną użyte do aktualizacji. - Usuwa wiersz z
Code = 1101
(na przykład) bezpośrednio z bazy danych, tzn. nie używaszDataTable
tutaj. Jest to emulacja innego użytkownika usuwającego wiersz za pomocąCode = 1101
z innej aplikacji. Lub jakaś inna część kodu usuwająca wiersz zCode = 1101
. - Wybiera wiersz z
Code = 1101
zDataTable
, ma to na celu pokazanie, że nadal tam jest, mimo że usunąłeś go z samej bazy danych. - Edytuje
Quantity
kolumna w wierszu zCode = 1101
wDataTable
. Należy to zrobić, w przeciwnym razie wywołanie Update zignoruje ten wiersz podczas aktualizacji. - Wykonuje aktualizację, spowoduje to zgłoszenie wyjątku, ponieważ próbujesz zaktualizować wiersz, który (już) nie istnieje w bazie danych.
Jeśli chcesz zaimplementować Last Writer Wins
, Dodaj następujący kod:
cb.ConflictOption = ConflictOption.OverwriteChanges;
Jest jeszcze jedna możliwa rzecz:jeśli masz Decimal
/numeric
jako kolumny w DB mogą powodować ten błąd, nawet jeśli dane wyglądają tak samo. Wynika to z błędu zaokrąglania dziesiętnego.
Ważna uwaga :Zawsze należy używać parameterized queries
Przy okazji. Tego rodzaju konkatenacje ciągów są otwarte dla SQL Injection
.