My code keeps throwing a DBConcurrencyException ("Concurrency violation: the DeleteCommand affected 0 of the expected 1 records.) when I make a second update to the data table.
The problem actually happens on a table that is linked to a parent table. The two tables, CashReceipts and CashReceiptsApplyTo are displayed on the same winform, and when I delete two cash receipts the update on cash receipt apply to's table fails with the dbconcurrencyexception (the table is updated everytime the binding source [linked to a binding navigator] changes position).
Here is my code:
protected override void saveToDatabase() {
tblCashReceiptsBindingSource.EndEdit();
tblCashReceiptsTableAdapter.Update(rentalEaseDataSet.tblCashReceipts);
//update the datatable
foreach (DataGridViewRow viewRow in viewApplications.Rows) {
if (viewRow.Cells[colAppID.Index].Value == null || viewRow.Cells[colApplyTo.Index].Value == null) {
continue;
} else if ((int)viewRow.Cells[colAppID.Index].Value == -1) {
insertNewRow(viewRow);
} else {
updateRow(viewRow);
}
}
try {
tblCashReceiptsApplyToTableAdapter.Update(rentalEaseDataSet.tblCashReceiptsApplyTo);
//tblCashReceiptsApplyToTableAdapter.Fill(rentalEaseDataSet.tblCashReceiptsApplyTo); );
} catch (Exception e) {
Bitmap bitmap = new Bitmap(this.Width, this.Height);
this.DrawToBitmap(bitmap, new Rectangle(0, 0, this.Width, this.Height));
saveScreenshot(this.GetType().FullName, e.Message, bitmap);
MessageBox.Show("There was an error saving your changes. This means that you should close the form, and re-enter the last Receipt you entered.\n\nPlease report this.");
}
}
The insertNewRow, and updateRow are simple:
private void updateRow(DataGridViewRow viewRow) {
//be forgiving
if ((int)viewRow.Cells[colAppID.Index].Value == -1) {
insertNewRow(viewRow);
return;
}
//find row in table, if it's not there, crash and burn
RentalEaseDataSet.tblCashReceiptsApplyToRow updateRow = rentalEaseDataSet.tblCashReceiptsApplyTo.Select("ID = " + viewRow.Cells[colAppID.Index].Value.ToString())[0] as RentalEaseDataSet.tblCashReceiptsApplyToRow;
updateRow.BeginEdit();
updateRow.CashReceiptsID = (int)viewRow.Cells[colCashReceipt.Index].Value;
updateRow.ApplyTo = (int)viewRow.Cells[colApplyTo.Index].Value;
updateRow.Paid = CurrencyToDecimal(viewRow.Cells[colPaid.Index].Value);
if (viewRow.Cells[colMemo.Index].Value != null) {
updateRow.Memo = viewRow.Cells[colMemo.Index].Value.ToString();
} else {
updateRow.SetMemoNull();
}
updateRow.EndEdit();
}
private void insertNewRow(DataGridViewRow viewRow) {
//be forgiving
if ((int)viewRow.Cells[colAppID.Index].Value != -1) {
updateRow(viewRow);
return;
}
RentalEaseDataSet.tblCashReceiptsApplyToRow newRow = rentalEaseDataSet.tblCashReceiptsApplyTo.NewRow() as RentalEaseDataSet.tblCashReceiptsApplyToRow;
newRow.CashReceiptsID = (int) viewRow.Cells[colCashReceipt.Index].Value;
newRow.ApplyTo = (int) viewRow.Cells[colApplyTo.Index].Value;
newRow.Paid = CurrencyToDecimal(viewRow.Cells[colPaid.Index].Value);
if (viewRow.Cells[colMemo.Index].Value != null) {
newRow.Memo = viewRow.Cells[colMemo.Index].Value.ToString();
}
rentalEaseDataSet.tblCashReceiptsApplyTo.Rows.Add(newRow);
//update the ID
viewRow.Cells[colAppID.Index].Value = newRow.ID;
}
Any idea why it would throw that error on the second delete?