Pull All at Once and Push Individually

Pull All at Once and Push Individually

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


chiefy81 posted on Friday, December 01, 2006

Can someone enlighten me as to why the preference in CSLA seems to be pull everything down (select root and children) with a single stored proc and call to the DB, but when updating, the various update methods are called for each of the BOs?  It would make sense that you could individually pull all of the BOs from the DB or likewise write a big update stored proc too.  Why mix and match?

ajj3085 replied on Friday, December 01, 2006

Because to have a single proc to do all the updates would result in a large, complex, unmaintainable stored procedure, where as the select procedure is just a few select statements in a row.  You also gain some performance benefits. 

Although, FWIW, I usually have the root pull itself, then have the child collection pull all the children.  I think keeping the children's data retreive out of the parent is worth the multiple db hit as the parent doesn't know to know anything of how the children are stored.

Trust me, I once tried the 'one proc to update them all' approach, and just calling the stupid thing was hard, nevermind trying to maintain it.

chiefy81 replied on Friday, December 01, 2006

ajj3085, my main issue is that I believe that pulling everything at once is getting complex, and also running into the grandchildren problem that is mentioned on the board various times.   I have no interest in implementing the one update procedure, sounds like a night mare :-). 

I am thinking of implementing the child select pulls as seperate stored proc calls.   This helps out with the simplicity of the development for us but will be a hit in performance, especially if we went to distributed.  Right now the web server and db server are on the same machine (its not a very large application) so I think we can get away with that. 

Any further thoughts on this approach?  A minor optimization might be to lazy load too.  Of course this still hurts performance, but as I mentioned that is not the priority. 

ajj3085 replied on Friday, December 01, 2006

Hi,

There's no reason you can't load via seperate stored procedure calls; you just end up with more than one call.  As I meantioned before, this is actually how I code my classes; the collections know how to get the data by looking at the parent.  I use internal static factory methods just like you would for a root object to do so.

Lazy loading may end up being more of a pain, some have had problems with it. Not the lazy loading, but the effect the missing data has on the parent's behavior.  Of course that may not be a problem for you.

HTH
Andy

chiefy81 replied on Sunday, December 03, 2006

Is there a methodology that is more suited for web based applications vs thick client apps?  It seems as though there would be somes preferences knowing which kind of app.

ajj3085, can you send of some samples of your classes for reference?

Thanks,

ajj3085 replied on Monday, December 04, 2006

Rocky and others recommend that you only do root objects for web applications, because you usually have a lack of state.  Thick clients usually are built like the sample application.

here's an example of the loading:

public class Root : BusinessBase<Root> {
    public Children MyChildren {
          get { return myChildren; }
          private set { myChildren = value; // usually you also hook up event handler for ListChanged }
    }

    // Static factory method as usual

    private void DataPortal_Fetch( SomeCriteria crit ) {
       // one (or more, if the root uses data from multiple tables) sql call to get the root object's data
       MyChildren = Children.GetChildren( this );

       ValidationRules.CheckRules();
    }
}

public class Children : BusinessListBase<Children, Child> {
       internal static Children GetChildren( Root parent ) {
             Children result;

             result = new Children();
             result.LoadSelf( parent );
       }

       private void LoadSelf( Root parent ) {
             // Get children in one sql call, using parent
       }
}

That's the jist of it.

chiefy81 replied on Monday, December 04, 2006

Yes, using root objects makes sense for web apps, thats what I have been doing so far as well.

Thanks for including the same code.  Would you use the code you mentioned the same way if the children are a list or just a single child?  Passing the Parent and letting the child figure out what parent data to use to fetch the data?

I was thinking it might be easier to do something like this:

public class Root : BusinessBase<Root> {

    int ChildID;  

    public Child MyChild {
          get { return myChild; }
          private set { myChild = value; // usually you also hook up event handler for ListChanged }
    }

    // Static factory method as usual

    private void DataPortal_Fetch( SomeCriteria crit ) {
       // one (or more, if the root uses data from multiple tables) sql call to get the root object's data
       MyChild = Child.GetChild( this.ChildID );

       ValidationRules.CheckRules();
    }
}
}

That way you are using the ID of the child and other BOs can use the same function because its not tied to the parent.  Let me know your thoughts on that.

Likewise for a list of children you could call ChildList.GetChildListBySomeValue(int somevalue) from the parent to load those children.

Thanks


ajj3085 replied on Monday, December 04, 2006

Yes, it'd be pretty much the same for non-collection children objects as well, except you'd listen to the PropertyChanged event instead of ListChanged.

Yes, I usually pass the parent, that way the parent doesn't need to know what data the child would need to load itself, so if the child starts using different data from the parent to load, the parent object doesn't need to change the GetChild call, it still just passes itself to the child.

That's my thinking at a least.

xAvailx replied on Monday, December 04, 2006

>> Rocky and others recommend that you only do root objects for web applications <<

In which post/blog entry has Rocky recommended only to use root objects for web applications? Any references are appreciated.

Thx.

ajj3085 replied on Monday, December 04, 2006

First, after finding the post, its not quite as general as that.. it depends on if you're going to use any session state on the web server, which you probably won't be on a high traffic site.

Here's a post though.

JoeFallon1 replied on Tuesday, December 05, 2006

For what it's worth:

I do not follow that recommendation for web projects. I use Session state for my BOs which are normal Root, Childcollection, child type BOs. This works out fine when I decide to re-use them in a Windows app. I am not sure why this paradigm keeps getting pushed on web developers - I am certainly not in favor of it.

Joe

 

 

ajj3085 replied on Tuesday, December 05, 2006

Joe,

The recommendation seems to be for high traffic sites, where using Session can hurt performance enough that using session at all is no longer an option.

Once you lose the ability to use session, you don't really have any other choice but to use only root objects.

pelinville replied on Wednesday, December 06, 2006

JoeFallon1:

For what it's worth:

I do not follow that recommendation for web projects. I use Session state for my BOs which are normal Root, Childcollection, child type BOs. This works out fine when I decide to re-use them in a Windows app. I am not sure why this paradigm keeps getting pushed on web developers - I am certainly not in favor of it.

Joe

I push it simply because I got burnt once. Badly. Designed a web site that was only going to support 200-300 users according to my boss.  I was guaranteed this.

Well, the day 2000 people tried to use the site at the same time I got blamed.  And three weeks of extra long days to get it working and a whole bunch of angry people later I swore I would never let that happen again.

But you are right that many web sites can use session to store objects between calls.  Even on a "high traffic" site I am sure if you put enough effort and was careful enough you could do it for thousands of users. (There are some things in this case you have to watch out for.  If you have to switch to another form of session managment like sql server, performance can be hit hard even though scalability might be fine.)

I would like to ask why everybody thinks that the "all root" approach is any more difficult to use in a windows form application than the "traditional root-child" approach.  It isn't. I believe it is actually easier and much more flexible. It is only the initial design that is more difficult. (And not that much more difficult once you get into the right mindset.)

xAvailx replied on Wednesday, December 06, 2006

>> which you probably won't be on a high traffic site. <<

Well...define high traffic. We have a few fairly "large" custom web applications that use CSLA which in average support 300-500 concurrent users per application. We are using session state (with great care) and have not encountered any issues. The total concurrent number may be high traffic for some, or puny to others...

While it is true that not using session state will be less taxing on the server, I think the decision/advice to others of using or not using session state should be treated on a case by case basis (ideally making a decision based on prototyping or using a stress test tool).

My $0.02

Thx.

ajj3085 replied on Wednesday, December 06, 2006

Hmm... high traffic site:  a site used by enough concurent users that maintaining any session state is not feasable.  Smile [:)]

In the context of the internet, I'm not sure 500 concurrent users is really that many at all.  A former coworker of mine has worked on some campbells sites, and I know session state starts to be an issue for them.

Andy

simon_may replied on Friday, December 01, 2006

Performance. You do more reading than writing. I once read that on average an application witll read ten times more data that it will write so it makes sense to optimise the read process and as Andy says its a lot easier to achieve.

Simon

Fintanv replied on Friday, December 01, 2006

You are, of course, free to change the approach based on your particular need.  For instance in many of the objects we create, the child collections are actually ranges of discreet time period data points.  We found it is therefore much better performance-wise for the collection to scan through its children for consecutive periods holding the same data values.  We then call one stored procedure per range (min_time, max_time, value).  Cuts down on the number of transactions going to the database.  More logic in the parent collection, but this can be abstracted out so the end cost is minimal.

 

pelinville replied on Saturday, December 02, 2006

I do the exact opposit.  Objects (or collections of them) are loaded individually.  Updates are all done in a single call to the remoted dataportal (but still individual calls to the DB)
 
I do this because I have no idea which data is needed but I always know what needs to be updated.
 
So as others have said that is primarily due to the nature of the needs of the application.  The CSLA example application is simple (by design) and constrained in it's needs.  If you have an application where you can predict what will be needed then it is very good to get the data in one call.
 
If you have an app in which the user can take many paths and you have no idea what data is needed next then getting that information up front may not make sense.
 
There is a very good book that discusses these issues, and many, many more. It is called effective enterprise java by ted neward.  Great book.  Almost as good as Rockys.  It looks at problems faced by developers in a realistic and comprehensive way. It is great because it doesn't use hype or even pretend that there is a magic bullet. 

Copyright (c) Marimer LLC