Това е така, защото DataAdapter
използва Optimistic Concurrency
по подразбиране. Това означава, че ако се опитвате да актуализирате ред, който вече не съществува в базата данни или е променен, актуализацията от DataAdapter
ще се провали с изключението по-горе.
Възможни сценарии :
- Между избора на данните в клиента и изпращането на актуализацията, друг потребител изтрива или актуализира този ред от приложението си.
- Възможно е да изтривате данните от някъде другаде в приложението си.
Например :
- Попълвате
DataTable
който ще се използва за актуализацията. - Изтрива реда с
Code = 1101
(например) директно от базата данни, т.е. не използватеDataTable
тук. Това емулира друг потребител, който изтрива реда сCode = 1101
от друго приложение. Или някаква друга част от вашия код, изтриваща реда сCode = 1101
. - Избира реда с
Code = 1101
отDataTable
, това е само за да покаже, че все още е там, въпреки че сте го изтрили от самата база данни. - Редактира
Quantity
колона в реда сCode = 1101
вDataTable
. Това трябва да се направи, в противен случай извикването на Update ще игнорира този ред при актуализиране. - Изпълнява актуализацията, това ще доведе до изключение, тъй като се опитвате да актуализирате ред, който (вече не) съществува в базата данни.
Ако искате да приложите Last Writer Wins
, Добавете следния код:
cb.ConflictOption = ConflictOption.OverwriteChanges;
Също така има още едно възможно нещо:ако имате Decimal
/numeric
като колони в DB те могат да причинят тази грешка, въпреки че данните изглеждат еднакви. Това се дължи на грешка при закръгляването на десетичната запетая.
Важна забележка :Винаги трябва да използвате parameterized queries
между другото. Този вид конкатенации на низове са отворени за SQL Injection
.