Complex BO question


Author
Message
Michael Cobb
Michael Cobb
StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)
Group: Forum Members
Posts: 26, Visits: 1K
I have a complex BO that contains a number of additional BOs.  For simplicity, my complex BO is called MainBO which instantiates _BO1, _BO2 and _BO3 (these are private BOs contained within MainBO).  _BO1 has columns called test1, test2, and test3.  _BO2 has columns called test4, test5 and test6.  _BO3 has columns called test7 and test8.  I have exposed these columns through Custom Field Properties and each is bound to a form.  Each is populated through a scalar query executed during the Custom Field's Property Get procedure.  The form only has MainBO dropped on it.  When running the form, as I navigate through records everything works perfectly.  When I click the edit toolstrip button, all of these fields become editable.  If I edit fields that were originally part of MainBO, the values save properly.  If I edit the fields exposed through MainBO such as test1, the Property Set procedures work perfectly.  The problem is that clicking the save button causes Property Gets to fire, so the new values for test1 - test8 get reset to their original values before they can be saved.  I am trying to save these secondary BOs in the BeforeSave event for MainBO, but by the time that code executes, the values for test1 - test8 have already been reset.

Is putting the code to retrieve the appropriate values for the secondary BOs in Property Get procedures a bad idea?  If so, where should that code be placed?  Better yet, is this the approach I should be using?

I'm not sure if it makes a difference but I'm using the StrataFrame Maintenance form so the initial save to MainBO is called through the MaintenanceFormToolStrip.

To complicate this further, what if the records I want to retrieve from _BO2 and _BO3 are dependent on values from _BO1?  Basically, MainBO and _BO1 can be thought of as a logical "record" although the values are spread across two tables (and I cannot redesign the db).  The only keys defined in the database are primary keys for each table represented by the BOs.  There are no foreign keys defined in the database-- all of the fk relationships are managed by existing software code.  I need to be able to save values first to _BO1 and then to MainBO, and each of these may contain lookup values that correspond to columns in _BO2 and _BO3.

This is my first complex BO in the real world, so once I am able to get past this hurdle I will test the Add/Delete functionality and if everything works I'll be able to use this as a model for other complex BOs.

Thanks,

Michael Cobb

StrataFrame Team
S
StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)
Group: StrataFrame Developers
Posts: 3K, Visits: 2.5K
The data binding of .NET likes to refresh the values between the controls and the data source often; there's really no way around it.  However, on your MainBO, you can override the Save() method and at the top, set a flag like _Saving to true.  Then call MyBase.Save() and then set the _Saving flag back to false.  In the gets of your custom properties, you can test the _Saving flag and just return the current cached value instead of retrieving the new one if you're saving. 
Michael Cobb
Michael Cobb
StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)
Group: Forum Members
Posts: 26, Visits: 1K
OK I think that will work but I have another question.  Where is the best place to put the fill code for a secondary BO like _BO1?  This business object needs to be filled with data so that the MainBO can expose some of its fields through Custom Field Properties.  Keep in mind that there are additional secondary BOs like _BO2 that are dependent upon the data in _BO1, and fields from _BO2 are also exposed through Custom Field Properties in MainBO.

Thanks!

Michael Cobb
Michael Cobb
StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)
Group: Forum Members
Posts: 26, Visits: 1K
Another detail to add to the last post:  _BO1 is dependent on values from MainBO.  So what I need to do is load _BO1 and then _BO2 with data as the MainBO is loading.  After the form and MainBO are loaded, should I reload _BO1 and _BO2 during the MainBO_Navigated event to keep these in sync?
StrataFrame Team
S
StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)
Group: StrataFrame Developers
Posts: 3K, Visits: 2.5K
If you can fill all 3 and they stay in sync until you refill them again, then you could just write a custom Fill method on MainBO and have it fill all of the business objects in the necessary order.  However, if the data within _BO1 and _BO2 is dependent upon the selected record in the MainBO, then yes, putting the refill of _BO1 in the Navigated of MainBO and the refill of _BO2 in the Navigated of _BO1 would be your best bet.
Michael Cobb
Michael Cobb
StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)
Group: Forum Members
Posts: 26, Visits: 1K
Thanks for the advice.  Now I have some new issues.  If I put the code to load _BO1 and _BO2 in the MainBO_Navigated event, the application returns errors when I open the form.  I receive {"The CurrentRow could not be evaluated because the CurrentRowIndex is out of range.  Business object record count: 0.  CurrentRowIndex: -1."} when the MainBO custom property field that exposes _BO1.test1 tries to bind to the form.  Since the MainBO.Navigated event has not yet occurred, the property get fails.

Another complication is that _BO1 may not contain data matching MainBO, and _BO2 may not contain data matching _BO1.  Each is dependent on its predecessor.  In a SQL analogy, MainBO left joins _BO1 which left joins _BO2.

Anyway, what I really need is some way to make sure that MainBO is fully loaded before _BO1 and _BO2, and that the data binding occurs after all of them are loaded.  Then when I move through the records of MainBO, I need to be able to retrieve the appropriate values for _BO1 and then _BO2.

Any thoughts?

StrataFrame Team
S
StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)
Group: StrataFrame Developers
Posts: 3K, Visits: 2.5K
It's fine that you leave the population of _BO1 and _BO2 in the MainBO.Navigated and _BO1.Navigated events respectively.  All you need to do is test on the BO.IsEmpty property (which if you don't have, since it was added in 1.6.1, you can test .Count = 0) to make sure that there are records in the BO before you try to work with it.  Also, I would recommend populating the MainBO within the ParentFormLoading event.  The ParentFormLoading event fires before any of the controls are bound, so, if you fill MainBO within it, the Navigated event will fire when the MainBO is filled, and the other 2 business objects will then be filled within that event.  It would also be recommended to test the .IsDirty property in your custom business objects, because while you should normally have some records, you might run into a case where you legitimatly don't have any records, so you would need to prepare and test for that condition.
Michael Cobb
Michael Cobb
StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)
Group: Forum Members
Posts: 26, Visits: 1K
From your reply, I'm inferring that I should just load some record from within the MainBO_ParentFormLoading event so that the form will load properly, and then in the FormLoad event I would call any code to retrieve data based on user supplied criteria (this form will probably be launched from a search dialog).  Is this correct?

I'm still having a problem.  In MainBO, I have a call to a custom fill method for _BO1 like the following:  _BO1.CustomFillMethod(Me.Field).  The first 5 records in my sample do not have associated _BO1 records, and the last 3 records do.  When I get to the 6th record, the _BO1 data is not populated.  When I leave that record, the _BO1 data for record 6 appears with the record I navigate to.  In essence, as I navigate the records the form displays the values from the previous _BO1 record, not the current _BO1 record.  Does this mean that the parameter I'm passing isn't being updated with the current record's value in MainBO before it hits the Navigated event?  It worked before when I was calling a fill method for _BO1 within each Property Get, but as soon as I put the code to load _BO1 in the MainBO_Navigated event this problem began occurring.  I also removed all calls to load _BO1 from within the Property Gets (inefficient anyway though it did work), but still the records aren't in sync.

StrataFrame Team
S
StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)StrataFrame Developer (4.6K reputation)
Group: StrataFrame Developers
Posts: 3K, Visits: 2.5K
When the Navigated method is called, the record should be in the right location.  There is a Navigating event that gets raised just before the record is actually navigated, so it will have the old value.  However, you shouldn't have the previously navigated record if you're using the Navigated event.  If you put a breakpoint in the Navigated event handler, is the _MainBO.CurrentRowIndex of the business object set properly when you're trying to call the custom fill method on _BO1?
Michael Cobb
Michael Cobb
StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)StrataFrame Beginner (36 reputation)
Group: Forum Members
Posts: 26, Visits: 1K
You are correct.  It is retrieving the proper value but just not updating the custom field property with the updated value from _BO1.  The form is not displaying the updated values for the MainBO custom fields that are based on values stored in _BO1 and _BO2.  Based on this, I added lines to my MainBO_Navigated event to call the property sets for the custom fields after retrieving the data from _BO1 and _BO2.  Unfortunately, even though I call the Property Set and pass it the appropriate value, the field on the screen continues to display the value for the previous record.  Is there something I need to do to force the screen to update with the current custom field property value that is being set in the MainBO_Navigated event?
GO

Merge Selected

Merge into selected topic...



Merge into merge target...



Merge into a specific topic ID...




Similar Topics

Reading This Topic

Login

Explore
Messages
Mentions
Search