StrataFrame Forum

Updating grand child when saving parent (RegisterForeignKey)

http://forum.strataframe.net/Topic18089.aspx

By Edhy Rijo - 7/25/2008

Hi All,

I am having problem updating a grand child record when saving the parent.  I attached a small VB sample project using the SF Sample tables Customers, Orders and OrderItems.

I created the main form frmCustomers which is used to add Customer, then the orders are added via a ChildFormDialog frmOrders and the OrderItems are added programmatically, and here is the problem, when clicking the Save button in frmCustomers, the Customers and Orders records are saved and the or_Cust_PK is updated properly, but the record for OrderItems is not saved and I believe the problem is that the field orit_or_pk is not being updated with its parent field value.

To test do the following:

  1. Add a new record in frmCustomers form (I added default values for all adding)
  2. Add a new Order from the Order's listview toolbar.
  3. Add a new Order Item from the frmOrders form.  (This will add a record programmatically with a orit_Prod_PK = 235)
  4. Click OK in frmOrders form.
  5. Click the Save button in the frmCustomers toolbar.
  6. In the Orders listview, Edit the Test PO record.
  7. Notice that there is no Order Item record created, and I have not been able to find out why.

Notice that all I am trying to do here is to implement the logic of saving all BOs in at a single point, in this case the frmCustomers form's Save button.

By Dustin Taylor - 7/28/2008

You're close! Your BOs and relationships are set up correctly, you just have a couple small issues on populating the BOs and programatically creating that record w00t.

The reason your orderitems aren't getting saved is that you are doing a FillByParentPrimaryKey in the Navigated event of the orders business object. This event gets fired when you return from the Orders child form. As a result, any changes to your OrdersItems business object were getting overwritten once you returned to the parent form.

Rather than loading the orders and order items in seperate queries (which requires a server trip every time you click an item in the orders list), I'd recommend you do a FillMultipleDataTables whenever you pick the customer you want to work with, and then just filter BizOrderItems1 down to the pertinate records on the navigate of BizOrders1. In effect, BizOrderItems1 will contain all orderitems records for all orders associated with the selected customer but, due to the filter, will only show the orderitems for the currently selected order. This would be a much more efficient approach in terms of server trips, and has the added benifit of not clearing out your grandchild BO every time the child BO navigates Wink.

You would call FillMultipleDataTables on the BizCustomers1 navigated event of the Customers form to make it work as it stands.

    Private Sub BizCustomers1_Navigated(ByVal e As MicroFour.StrataFrame.Business.NavigatedEventArgs) Handles BizCustomers1.Navigated
        '-- Get all Orders for the current Customer.
        If BizCustomers1.Count > 0 AndAlso BizCustomers1.Then
            ' Call FillMultipleDataTables here
        End If
        lvOrders.Requery()
    End Sub

Note: The above is how to make it work in your existing form, but it isn't how we would typically do it. From a form-design standpoint, we don't typically load a bunch of records and then use forward and back buttons to navigate through them. Instead, we typically call a browse, pick the specific customer record to work with, and then call FillMultipleDataTables upon the return of the browse form.

That will keep your order items from being overwritten. To get them to actually save, you'll need to address a couple of things when you programatically create the record. You would have seen and corrected these yourself, I'm sure, but since I was already in there, I thought I would point them out Smile.

On the orders form, change this:

    Private Sub cmdAddToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAddToolStripMenuItem.Click
        Me.BizOrderItems1.NewRow()
        Me.BizOrderItems1.orit_or_pk = Me.BizOrders1.or_pk
        Me.BizOrderItems1.orit_prod_pk = 235

        Me.lvOrderItems.Requery()
    End Sub

To this:

    Private Sub cmdAddToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdAddToolStripMenuItem.Click
        Me.BizOrderItems1.NewRow()
        Me.BizOrderItems1.orit_or_pk = Me.BizOrders1.or_pk
        Me.BizOrderItems1.orit_prod_pk = 1

        Me.lvOrderItems.Requery()
    End Sub

Basically, you don't need to set the orderitems primary key (it does it for you), but you do need to specify a valid product id (in production, you'll likely need some kind of user input rather than hardcoding a specific product.)

Hope it helps! BigGrin

By Edhy Rijo - 7/28/2008

Hi Dustin,

Thanks for taking the time to review the sample project.  I will review your post in detail and make the changes in the sample project before changing my project.

I have not used the FillMultipleDataTable, and guess it is now time to start using it.  In my project I use a Browse Dialog in the main form, but due to time to create the sample project I when the easiest way by just selecting TOP 100.  From my quick review, I noticed the main cause was the filtering of the order item table, which after you explained it, makes perfect sense.

By Dustin Taylor - 7/28/2008

I suspected as such, sounds good. FYI -There are multiple examples of FillMultipleDataTables in the maintenance forms of the StrataFlix sample, as well as how we utilize the browse on maintenance forms.



Good luck! Smile
By Edhy Rijo - 7/30/2008

Hi Dustin,

Just to let you know that using FillMultipleDataTables worked, and not only that, it minimized the amount of code I used before.

By Trent L. Taylor - 7/30/2008

Good to hear! Smile