Vì vậy, tôi có datagridview này được liên kết với một nguồn ràng buộc đó là ràng buộc với một bảng dữ liệu cơ bản. Vấn đề là tôi cần phải hướng dẫn thêm hàng vào datagridview.Tai họa dữ liệu ràng buộc
Điều này không thể thực hiện được trong khi bị ràng buộc, vì vậy tôi phải làm việc với dữ liệu.
Nếu tôi thêm các hàng vào dữ liệu có thể định trước, khi dữ liệu được lưu, các hàng được sao chép, có thể vì nguồn ràng buộc bằng cách nào đó đã giữ một bản sao và chèn nó vào.
Thêm nó vào nguồn ràng buộc là những gì tôi đã cố gắng làm nhưng nó không hoạt động.
Hãy để tôi giải thích chính xác những gì thiết lập của tôi là:
Tôi có một cơ sở dữ liệu với hai bảng: CashReceiptTable và CashReceiptItemsTable
CashReceiptItemsTable chứa một FK để CashReceiptTable.
Biểu mẫu cho phép người dùng thêm và sửa đổi hai bảng.
Khi người dùng nhập mã rút tiền mặt mới, id của biên nhận tiền mặt là -1 và FK bằng cashReceiptitemstable là -1. Khi cơ sở dữ liệu được lưu, id của cashReceipt được cập nhật và tôi phải tự cập nhật FK của cashreceiptitem.
Dưới đây là những vấn đề:
Khi tôi cố gắng cập nhật các CashReceiptID (FK) trong hơn một hàng trong cashreceiteitems ràng buộc nguồn, hàng đầu tiên được cập nhật, và biến mất (vì nó lọc), và các hàng khác bị xóa và tôi không thể truy cập chúng nữa.
Tôi không biết tại sao điều này lại xảy ra, tôi chưa cập nhật bộ lọc nên vẫn nên ở đó, nhưng cố gắng truy cập chúng sẽ ném RowNotInTableException.
Tôi đã quản lý công việc xung quanh sao chép các hàng trong nguồn ràng buộc vào một mảng bộ nhớ, xóa hàng đầu tiên trong nguồn ràng buộc (tất cả các hàng khác chỉ biến mất), cập nhật FK của hàng và lắp lại chúng vào nguồn ràng buộc và lưu bảng.
Điều này không sao, nhưng tại sao các hàng lại biến mất?
Tôi cũng gặp một vấn đề nhỏ nữa. Khi CashReceiptsTable trống và tôi thêm một hàng mới vào nó, nếu tôi thêm nhiều hơn một hàng vào CashReceiptsItemTable nó gây ra vấn đề. Khi thêm thủ công các mục vào nguồn ràng buộc, thêm một hàng mới sẽ bật lên hàng trước đó và đẩy nó vào dữ liệu có thể định trước được. Điều này ẩn nó khỏi thói quen cập nhật FK của tôi và nó bị mất, nó cũng loại bỏ nó khỏi DataGridView.
Nó chỉ làm điều đó khi tôi thêm hàng đầu tiên vào CashReceiptsTable. Tại sao nó làm điều này, và làm thế nào tôi có thể sửa nó?
tôi gửi bài mã của tôi rằng autopopulates nó ở đây:
private void autopopulate(decimal totalPayment) {
//remove old rows
for (int i = 0; i < tblCashReceiptsApplyToBindingSource.List.Count; i++) {
DataRowView viewRow = tblCashReceiptsApplyToBindingSource.List[i] as DataRowView;
RentalEaseDataSet.tblCashReceiptsApplyToRow row = viewRow.Row as RentalEaseDataSet.tblCashReceiptsApplyToRow;
if (row.CashReceiptsID == this.ReceiptID) {
tblCashReceiptsApplyToBindingSource.List.Remove(viewRow);
i--;
}
}
decimal payment = totalPayment;
//look for an exact amount
foreach (DataGridViewRow dueRow in dataViewDueRO.Rows) {
decimal due = -1 * (Decimal)dueRow.Cells[Due.Index].Value;
if (due == payment) {
String charge = (String)dueRow.Cells[Description.Index].Value;
int chargeID = ManageCheckbooks.findTransactionID(charge);
tblCashReceiptsApplyToBindingSource.AddNew();
RentalEaseDataSet.tblCashReceiptsApplyToRow row = ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row as RentalEaseDataSet.tblCashReceiptsApplyToRow;
row.CashReceiptsID = this.ReceiptID;
row.ApplyTo = chargeID;
row.Paid = payment; //convert to positive
payment = 0;
break;
}
}
//if the exact amount was found, payment will = 0, and this will do nothing, otherwise,
//divy out everything left over (which will be everything)
foreach (DataGridViewRow dueRow in dataViewDueRO.Rows) {
String charge = (String)dueRow.Cells[Description.Index].Value;
decimal due = (Decimal)dueRow.Cells[Due.Index].Value;
if (due > 0 || payment <= 0) {
continue;
}
int chargeID = ManageCheckbooks.findTransactionID(charge);
payment += due; //due is negative, so this will subtract how much the user owes
tblCashReceiptsApplyToBindingSource.AddNew();
RentalEaseDataSet.tblCashReceiptsApplyToRow row = ((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row as RentalEaseDataSet.tblCashReceiptsApplyToRow;
row.CashReceiptsID = this.ReceiptID;
row.ApplyTo = chargeID;
if (payment >= 0) {
//payment is enough to cover this
row.Paid = due * -1; //convert to positive
} else {
//doesn't have enough money to conver this, can only cover partial, or none
row.Paid = (due - payment) * -1; //math:
//money remaining $50, current charge = $60
//payment = 50 + -60 = -10
//row["Paid"] = (-60 - -10) * -1
//row["Paid"] = (-60 + 10) * -1
//row["Paid"] = -50 * -1
//row["Paid"] = 50
}
if (payment <= 0) {
break; //don't conintue, no more money to distribute
}
}
isVirginRow = true;
}
Và đây là chức năng mà lưu nó vào cơ sở dữ liệu:
protected override void saveToDatabase() {
tblCashReceiptsBindingSource.EndEdit();
isVirginRow = false;
RentalEaseDataSet.tblCashReceiptsRow[] rows = rentalEaseDataSet.tblCashReceipts.Select("ID < 0") as RentalEaseDataSet.tblCashReceiptsRow[];
int newID = -1;
if (rows.Count() > 0) {
tblCashReceiptsTableAdapter.Update(rows[0]);
newID = rows[0].ID;
}
tblCashReceiptsTableAdapter.Update(rentalEaseDataSet.tblCashReceipts);
//update table
/*foreach (RentalEaseDataSet.tblCashReceiptsApplyToRow row in rentalEaseDataSet.tblCashReceiptsApplyTo.Select("CashReceiptsID = -1")) {
row.CashReceiptsID = newID;
}*/
//update binding source
DataRowView[] applicationsOld = new DataRowView[tblCashReceiptsApplyToBindingSource.List.Count];
RentalEaseDataSet.tblCashReceiptsApplyToRow[] applicationsNew = new RentalEaseDataSet.tblCashReceiptsApplyToRow[tblCashReceiptsApplyToBindingSource.List.Count];
tblCashReceiptsApplyToBindingSource.List.CopyTo(applicationsOld, 0);
for (int i = 0; i < applicationsOld.Count(); i++) {
RentalEaseDataSet.tblCashReceiptsApplyToRow row = applicationsOld[i].Row as RentalEaseDataSet.tblCashReceiptsApplyToRow;
if (row.CashReceiptsID < 0) {
applicationsNew[i] = rentalEaseDataSet.tblCashReceiptsApplyTo.NewRow() as RentalEaseDataSet.tblCashReceiptsApplyToRow;
applicationsNew[i]["ID"] = row.ID;
applicationsNew[i]["CashReceiptsID"] = this.ReceiptID;
applicationsNew[i][2] = row[2];
applicationsNew[i][3] = row[3];
applicationsNew[i][4] = row[4];
//row.Delete();
}
}
for (int i = 0; i < applicationsOld.Count(); i++) {
try {
if ((int)applicationsOld[i].Row["ID"] < 0) {
applicationsOld[i].Row.Delete();
}
} catch (RowNotInTableException) {
break;
}
}
this.tblCashReceiptsApplyToBindingSource.Filter = "CashReceiptsID = " + this.ReceiptID;
foreach (DataRow newRow in applicationsNew) {
if (newRow == null) {
break;
}
tblCashReceiptsApplyToBindingSource.AddNew();
((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[0] = newRow[0];
((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[1] = newRow[1];
((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[2] = newRow[2];
((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[3] = newRow[3];
((DataRowView)tblCashReceiptsApplyToBindingSource.Current).Row[4] = newRow[4];
}
tblCashReceiptsApplyToBindingSource.EndEdit();
checkForBadRows();
tblCashReceiptsApplyToTableAdapter.Update(rentalEaseDataSet.tblCashReceiptsApplyTo);
tblCashReceiptsApplyToTableAdapter.Fill(rentalEaseDataSet.tblCashReceiptsApplyTo);
}
Tôi gặp vấn đề mà tôi nghĩ cơ bản giống nhau. Tôi nghĩ rằng vấn đề tổng thể là: Làm thế nào để thay đổi một DataTable, mà không làm rối loạn DataView bị ràng buộc trong giao diện người dùng? –
Bạn đã bao giờ nhận được một giải pháp về điều này? –