Důvodem je DataAdapter
používá Optimistic Concurrency
ve výchozím stavu. To znamená, že pokud se pokoušíte aktualizovat řádek, který již v databázi neexistuje nebo se změnil, aktualizace z DataAdapter
se nezdaří s výjimkou výše.
Možné scénáře :
- Mezi tím, co vyberete data do klienta a odešlete aktualizaci, jiný uživatel smaže nebo aktualizuje tento řádek ze své aplikace.
- Je možné, že smažete data odjinud ve své aplikaci.
Například :
- Vyplníte
DataTable
který bude použit pro aktualizaci. - Smaže řádek s
Code = 1101
(například) přímo z databáze, tj. nepoužíváteDataTable
tady. Toto je emulace jiného uživatele, který odstraňuje řádek sCode = 1101
z jiné aplikace. Nebo nějaká jiná část kódu, která odstraní řádek sCode = 1101
. - Vybere řádek s
Code = 1101
zDataTable
, je to jen pro ukázku, že tam stále je, i když jste jej smazali ze samotné databáze. - Upraví
Quantity
sloupec v řádku sCode = 1101
vDataTable
. Toto je nutné provést, jinak bude volání Update tento řádek při aktualizaci ignorovat. - Provede aktualizaci, vyvolá výjimku, protože se pokoušíte aktualizovat řádek, který (již) v databázi neexistuje.
Pokud chcete implementovat Last Writer Wins
, Přidejte následující kód:
cb.ConflictOption = ConflictOption.OverwriteChanges;
Také je zde ještě jedna možná věc:pokud máte Decimal
/numeric
jako sloupce v DB mohou způsobit tuto chybu, i když data vypadají stejně. To je způsobeno chybou zaokrouhlování desetinných míst.
Důležitá poznámka :Vždy byste měli používat parameterized queries
mimochodem. Tento druh zřetězení řetězců je otevřený pro SQL Injection
.