C'est parce que DataAdapter
utilise la Optimistic Concurrency
par défaut. Cela signifie que si vous essayez de mettre à jour une ligne qui n'existe plus dans la base de données ou qui a été modifiée, la mise à jour depuis le DataAdapter
échouera avec l'exception ci-dessus.
Scénarios possibles :
- Entre la sélection des données dans le client et l'envoi de la mise à jour, un autre utilisateur supprime ou met à jour cette ligne depuis son application.
- Il se peut que vous supprimiez les données ailleurs dans votre application.
Par exemple :
- Vous remplissez le
DataTable
qui sera utilisé pour la mise à jour. - Supprime la ligne avec
Code = 1101
(par exemple) directement depuis la base de données, c'est-à-dire que vous n'utilisez pas leDataTable
ici. Ceci émule un autre utilisateur supprimant la ligne avecCode = 1101
d'une autre application. Ou une autre partie de votre code en supprimant la ligne avecCode = 1101
. - Sélectionne la ligne avec
Code = 1101
depuis leDataTable
, c'est juste pour montrer qu'il est toujours là même si vous l'avez supprimé de la base de données elle-même. - Modifie la
Quantity
colonne dans la ligne avecCode = 1101
dans leDataTable
. Cela doit être fait, sinon l'appel à Update ignorera cette ligne lors de la mise à jour. - Exécute la mise à jour, cela lèvera l'exception puisque vous essayez de mettre à jour une ligne qui n'existe (plus) dans la base de données.
Si vous souhaitez implémenter Last Writer Wins
, Ajoutez le code suivant :
cb.ConflictOption = ConflictOption.OverwriteChanges;
Il y a aussi une autre chose possible :si vous avez Decimal
/numeric
en tant que colonnes dans la base de données, elles peuvent provoquer cette erreur même si les données se ressemblent. Cela est dû à une erreur d'arrondi décimal.
Une remarque importante :Vous devez toujours utiliser des parameterized queries
d'ailleurs. Ce type de concaténation de chaînes est ouvert pour SQL Injection
.