This is because DataAdapter
uses Optimistic Concurrency
by default. This means that if you are trying to update a row that no longer exists in the database or changed, the update from the DataAdapter
will fail with the exception above.
Possible scenarios:
- Between you selecting the data into the client and sending the
update, another user is deleting or updating this row from his application. - It can be that you are deleting the data from somewhere else in your application.
For example:
- You fill the
DataTable
that will be used for the update. - Deletes the row with
Code = 1101
(for example) directly from the database, i.e. you do not use theDataTable
here. This is emulating another user deleting the row withCode = 1101
from another application. Or some other part in your code deleting the row withCode = 1101
. - Selects out the row with
Code = 1101
from theDataTable
, this is just to show that it is still there even though you have deleted it from the database itself. - Edits the
Quantity
column in the row withCode = 1101
in theDataTable
. This has to be done, otherwise the call to Update will ignore this row when updating. - Executes the update, this will throw the exception since you are trying to update a row that (no longer) exists in the database.
If you want to implement Last Writer Wins
, Add the following code:
cb.ConflictOption = ConflictOption.OverwriteChanges;
Also there is one more possible thing : if you have Decimal
/numeric
as columns in the DB they may cause this error even though the data looks the same. This is due to a decimal rounding error.
An important note:
You should always use parameterized queries
by the way. This kind of string concatenations are open for SQL Injection
.