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
DataTablekterý bude použit pro aktualizaci. - Smaže řádek s
Code = 1101(například) přímo z databáze, tj. nepoužíváteDataTabletady. Toto je emulace jiného uživatele, který odstraňuje řádek sCode = 1101z jiné aplikace. Nebo nějaká jiná část kódu, která odstraní řádek sCode = 1101. - Vybere řádek s
Code = 1101zDataTable, je to jen pro ukázku, že tam stále je, i když jste jej smazali ze samotné databáze. - Upraví
Quantitysloupec v řádku sCode = 1101vDataTable. 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 .