Това е така, защото 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 .