2010-02-15 3 views
7

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.

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); 
    } 
+0

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? –

+0

Bạn đã bao giờ nhận được một giải pháp về điều này? –

Trả lời

1

Bạn có thể muốn thử thêm hàng vào DataGridView.Vì bạn đang ràng buộc với nó, DataGridView trở thành 'điểm truy cập' của bạn.

Tôi có một số ứng dụng liên kết với DataGridView và trong hầu hết các trường hợp khi tôi thêm hàng, tôi làm như vậy thông qua DataGridView. Nó đã có các thuộc tính/phương thức/sự kiện cho phép bạn thêm một cách dễ dàng.

Nếu bạn cần thêm một số thông tin tôi có thể cập nhật.

+0

Tôi nêu trong câu hỏi rằng nếu tôi thêm các hàng vào DataGridView, nó sẽ nhân bản chúng trong cơ sở dữ liệu. Tôi đã khắc phục sự cố này vào ngày sau khi đăng, nhưng tôi không nhớ bản sửa lỗi là gì. – Malfist

+0

Tất cả những gì tôi thấy là "Tôi thêm các hàng vào datatable cơ bản, khi dữ liệu được lưu, các hàng được nhân đôi,". Tôi không thấy bất cứ điều gì nói về datagridview và nhân đôi, nhưng tôi có thể bỏ lỡ nó. –

+0

Tôi phải suy nghĩ về một vấn đề khác mà tôi có. Xin lỗi, đi qua mã của tôi, tôi thấy rằng tôi đã thay đổi nó từ việc thêm một hàng vào tập dữ liệu để thêm một hàng vào chế độ xem dữ liệu, vì vậy tôi phải lấy lời khuyên của bạn. 'viewApplications.Rows.Add (đối tượng mới [] { -1, this.ReceiptID, chargeID, String.Format (" $ {0: N} ", paidThisTime), " " });' – Malfist