2
votes

Here's are the facts:

  1. I have a parent table, let's call it Order. The data in this table is viewed using a DataGridView (dgvOrder).
  2. I have a child table, let's call it OrderDetails. The data in this table is viewed using a DataGridView (dgvOrderDetails)
  3. I have textboxes (and checkboxes, comboboxes, etc.) that are databound to the Order table (using BindingSource).
  4. I am using Visual Studio 2008.

What I want to do:

dgvOrder is read-only. I use this to browse through records ala BindingNavigator. (I like to use a DataGridView for navigating records because it is intuitive. You immediately see what the next few records are all about.)

To add new records, I use a "new" button (uxNewButton). To save my updates, I use a "save" button (uxSaveButton). Records are added using the textboxes and not directly via dgvOrder. Child records are added directly via dgvOrderDetails.

dgvOrderDetails, I guess, is pretty obvious - it contains the details of the Order (1 to many relationship).

My code and configuration:

  • Hierchical Update (in the dataset designer) is set to true (by default in VS 2008)
  • Relationship between Order and OrderDetail is set as "both relation and fk constraint". Update and delete are set to cascade. Accept/Reject rule is set to "none". Nested Relation is unchecked.
  • TableAdapterManager is dragged to the designer(tam).

    private void uxNewButton_Click(object sender, EventArgs e) {

        bsOrder.AddNew();
    

    }

    private void uxSaveButton_Click(object sender, EventArgs e) {

        this.Validate();
        bsOrder.EndEdit();
        bsOrderDetails.EndEdit();
    
        tam.UpdateAll(dsOrder); //DataSet is named dsOrder. try-catch block excluded for simplicity
    

    }

Problem:

After filling up all the textboxes (and etc.) and the dgvOrderDetails, hitting the save button will cause an error: ForeignKeyConsraint FK_Orderchild_Order requires the child key values (-1) to exist in the parent table.

However, if I add a record directly using dgvOrder (then dgvOrderDetails), hitting the save button will save successfully.

I also found out that I can save successfully if I add new records using the textboxes but have to select a different row in dgvOrder, then selecting the current row again, before adding the records on dgvOrderDetails.

It seems like while adding a new record via the textbox, the underlying data is not synced with the DataGridView. Selecting a different row, then selecting back the current row syncs the data altogether.

I have tried various hacks in the save event like:

dgvOrder.Refresh(); //or

dgvOrder.Invalidate();
dgvOrder.Refresh(); // or

dgvOrder.Parent = null;
Controls.Add(dgvOrder);

//and so on and so forth (suggetstions from Google searches)
1
I forgot to mention that programmatically moving the dgvOrder selection before calling tam.UpdateAll() does not solve the problem.tonex
Adding bsOrder.EndEdit() on the Enter Event of dgvOrderDetail seems to solve the problem but I'm not sure if this is best practice.tonex

1 Answers

0
votes

Adding bsOrder.EndEdit() on the Enter Event of dgvOrderDetail seems to solve the problem but I'm not sure if this is best practice.