Declaring child collection in a collection

Declaring child collection in a collection

Old forum URL: forums.lhotka.net/forums/t/645.aspx


esteban404 posted on Monday, July 17, 2006

I have a 1.53 base BusinessBase object Project which has a collection of OrderNumbers. I want these Order#s to retrieve their header and details for display in a grid. The details are coming from our main frame so they must be read only collections.

So the end result is Project(BusinessBase) > Order# (BizCollectionBase) > OrderHeader(ReadOnlyCollectionBase) > OrderDetail(ReadOnlyCollectionBase)

Do I declare the collection for the detail in OrderHeader as a private member in the class outside the struct? Does it get populated by a datareader or with its own GetMethod then lock the Header list?

Sorry, I couldn't find an example. Here's my retrieval into the struct right now:
using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader()))
{
     locked =
false;
     while(dr.Read())
    {
       SOInfo info =
new SOInfo();
       info.ShipTo = dr.GetDecimal(0);
       info.BillTo=dr.GetDecimal(1);
       info.Type = dr.GetString(2);
       info.PONbr = dr.GetString(3);
       List.Add(info);
     }
//dr.NextResult() here?
     locked =
true;
}

_E

vargasbo replied on Monday, July 17, 2006

Hmmm, how you design your classes will depend on the behavior you’re looking. In my case, I only go down one depth in my graph. So I would load Project and Order, just like you have it now and not thee two other child collections.

The order object, it's what rocky calls a switchable object, meaning that you need it to act like a root sometimes and a child another time depending on who's calling it. In your order class, create a property and lazy load the order header & order details when this (order) class is acting as a child, when it's acting as a root, you'll just load one depth below it graph tree.

Hope that helps, if not, I can send you some code snippets.

Regards,
~Bo

esteban404 replied on Monday, July 17, 2006

Thanks for the reply ~Bo. The behavior. Hmm. That's a novella, but at the last, it is not switchable. It will never be a root object by internal law (SarBox constraints). I've used GreatGrandChildren in my stuff before, but this is just not behaving and I know I've seen this done. I just can't find the source.

I'm thinking a ROBusiness base would be better. I can build the detail collections inside those ROB objects and retrieve the children (or lazily). That's pretty much what's left over when the struct is removed from the ROCollectionBase. I haven't, but I think I can use ROBase.

See the Users can fill in some order number, but the details are not available until the following day. I think my ROBase idea may be better and lazy load the info. If the object IsNew, there's not use going to the db and I can use a creation date to determine if the data is available. There's a 24 hour delay. It's the situation I have, unfortunately. I'm thinkin that 24 hr delay would be a problem, too. What if they just forgot to enter it? Then it should actually be available. Guess I'll let the object try to load it and include a "failed date field" to prevent multiple hits to the server in the same 24 hr period.

What a kludge.

_E

RockfordLhotka replied on Monday, July 17, 2006

The short answer is that a collection can't directly contain a collection. You need an intermediate object to represent the child, and then that child can have a collection of children itself.

Project(BB)
  ->OrderNumbers(BCB)
    ->OrderHeader(ROB)
      ->OrderDetails(ROCB)
        ->OrderDetail(ROB)

Notice how I've added OrderHeader as an object in the middle here. Even if all it does is contain the collection, that's required.

esteban404 replied on Monday, July 17, 2006

RockfordLhotka:

The short answer is that a collection can't directly contain a collection. You need an intermediate object to represent the child, and then that child can have a collection of children itself.

Project(BB)
  ->OrderNumbers(BCB)
    ->OrderHeader(ROB)
      ->OrderDetails(ROCB)
        ->OrderDetail(ROB)

Notice how I've added OrderHeader as an object in the middle here. Even if all it does is contain the collection, that's required.

Thanks, Rocky. I did something slightly different on the car ride back. I'll review it against your suggestion, but i think my intermediate object is the header object.

What I created is a base collection of header items so they can be added/edited/deleted from the Project. They use BB and BCB. In the BB header item, I used a ROC object for property lazy loading. We'll check it for best fit tomorrow.

The data I'm reading in is odd in that it's not normalized, I don't know why they store it like that, but that's what I discovered was there. I'm glad it is presentable now. I showed the prototype to the Sales Manager. She noted they used to enter data into about 15 fields for this piece of the process. CSLA has reduced it to about 1 or 2.

Happy campers indeed!

_E

Copyright (c) Marimer LLC