Đ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
DataTable
sẽ đượ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 = 1101
từ 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 = 1101
từ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
Quantity
trong hàng cóCode = 1101
trongDataTable
. 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
.