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.