Điều này là do DataAdapter sử dụng Optimistic Concurrency theo mặc định. Điều này có nghĩa là nếu bạn đang cố gắng cập nhật một hàng không còn tồn tại trong cơ sở dữ liệu hoặc đã thay đổi, thì hãy cập nhật từ DataAdapter sẽ thất bại với ngoại lệ ở trên.
Các trường hợp có thể xảy ra :
- Giữa việc bạn chọn dữ liệu vào máy khách và gửi bản cập nhật, một người dùng khác đang xóa hoặc cập nhật hàng này khỏi ứng dụng của họ.
- Có thể bạn đang xóa dữ liệu từ một nơi khác trong ứng dụng của mình.
Ví dụ :
- Bạn điền vào
DataTablesẽ được sử dụng cho bản cập nhật. - Xóa hàng có
Code = 1101(ví dụ) trực tiếp từ cơ sở dữ liệu, tức là bạn không sử dụngDataTableđây. Điều này đang mô phỏng một người dùng khác xóa hàng bằngCode = 1101từ một ứng dụng khác. Hoặc một số phần khác trong mã của bạn xóa hàng cóCode = 1101. - Chọn ra hàng có
Code = 1101từDataTable, điều này chỉ để chứng tỏ rằng nó vẫn còn đó mặc dù bạn đã xóa nó khỏi cơ sở dữ liệu. - Chỉnh sửa
Quantitytrong hàng cóCode = 1101trongDataTable. Việc này phải được thực hiện, nếu không lệnh gọi Cập nhật sẽ bỏ qua hàng này khi cập nhật. - Thực hiện cập nhật, thao tác này sẽ loại bỏ ngoại lệ vì bạn đang cố cập nhật một hàng (không còn) tồn tại trong cơ sở dữ liệu.
Nếu bạn muốn triển khai Last Writer Wins , Thêm mã sau:
cb.ConflictOption = ConflictOption.OverwriteChanges;
Ngoài ra, có một điều khả thi nữa:nếu bạn có Decimal / numeric như các cột trong DB, chúng có thể gây ra lỗi này mặc dù dữ liệu trông giống nhau. Điều này là do lỗi làm tròn số thập phân.
Một lưu ý quan trọng :Bạn nên luôn sử dụng parameterized queries nhân tiện. Loại nối chuỗi này được mở cho SQL Injection .