Changing line focus in my grid make the item being saved

Changing line focus in my grid make the item being saved

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


albator posted on Tuesday, January 23, 2007

Hi,

My application contains multiple root objects that must be saved in a same transaction.  We made a command object that make this possible.

The problem is that we must only save by using this command object.  GUI must never call directly a root object save method.

We have a problem with EditableRootListBase<T>  , we bind a collection that inherits from EditableRootListBase<T> and the apply edit event raised by the grid when changing grid focus make the object being saved.

I'm not sure but maybe it is related to this code that I found in EditableRootListBase<T> :

#region IParent Members

void Csla.Core.IParent.ApplyEditChild(Core.IEditableBusinessObject child)

{

if (!_activelySaving && child.EditLevel==0)

SaveItem((T)child);

}

 

Is there a way to avoid object being saved when grid line lost focus?

Thanks

 

ajj3085 replied on Tuesday, January 23, 2007

Your design would seem to be flawed.  By definition, if you need something to be saved withing a single transaction, you have one root object which controls the other objects. 

It sounds like you're trying to reuse existing objects for another use case.  Instead, build a new set of objects specifically for your use case.

Also, ERLB is designed to save the changes immedately after the row 'commits' the changes.  If you don't want that behavior, you should not be using ERLB.

albator replied on Tuesday, January 23, 2007

Nothing says that good object design must use only one object for a use case.  Multiple objects should interact to make the Job done.

We are using collection of root object for performance purpose; our application is managing big sets of data.  Using EditableRootListBase<T> allow us to build changeset easyly, this way we avoid passing big collection of data to the second tier.

So is there a way to avoid root object being saved by the apply edit ?

One way could be to override SaveItem but I’m realy not sure it is the best choice.

Thanks

 

ajj3085 replied on Tuesday, January 23, 2007

albator:
Nothing says that good object design must use only one object for a use case.  Multiple objects should interact to make the Job done.


I think you misunderstood.  I didn't mean one object per use case, I meant one set of objects per use  case.  But you shouldn't be reusing objects from other use cases unless the behavior is identical in both use cases.  Since you have a problem where you have a few root objects which need to be saved as one transaction, that's a pretty good sign that you're attempting to reuse objects from other uses cases whose behavior is not identicatal (by definition, since the existing objects function within their own transaction isolation).

albator:
We are using collection of root object for performance purpose; our application is managing big sets of data.  Using EditableRootListBase<T> allow us to build changeset easyly, this way we avoid passing big collection of data to the second tier.

You should be designed objects to fulfill use cases.  Only after you have done so should you look at performance, and you should strive not to sacrafice design for performance.

albator:
So is there a way to avoid root object being saved by the apply edit ?

The behavior ERLB doesn't seem to fit your requirements, so I wouldn't suggest using it for this use case.  That class was added recently specifically to allow editing of root objects in a collection, whose changes should be saved after the grid commits the row. 

What you probably want is a BusinessListBase root object, but then all the items contained in the list would have to become children.  Since the objects should now be children, they should probably be different objects in their own right.  You might be able to create a switchable object (one that can be a child or root), but this usually indicates a design problem, and you should proceed with caution.

albator replied on Wednesday, January 24, 2007

Thanks for helping ajj3085,

 

I was trying to be succinct and bypass lots of business and design issues and used the performance aspect as a shortcut to explain the design which is of course wrong. Those root objects must indeed be root objects but while there is a performance benefit this is not the main reason. Those objects are used/refered by other objects but they do not "belong". They can be on their own or, if you prefer, "switch parent". And we are not reusing objects at all.

 

I think there are legitimate reasons to save multiple root objects in the same transaction although I admit it is the first time we have to deal with an ERLB. We are doing it with a command object that wraps the entire transaction from Rocky's recommendation (we met him before the ERLB issue and ERLB was not discussed at the time).

 

We may have goofed, but those objects are root objects because of their designed behaviors and we need a collection (in fact collections) of them and we must save them (the roots, not the collections) in a common batch transaction. This is working fine (we may not see the train ahead and this is also why we are posting) and the only issue is with the grid that is calling apply edit and bypassing transaction logic.

 

It seems to me that ERLB is assuming too much in this case by allowing the UI to take too much control.

 

I think that a switch for disabling save on apply edit could be a good solution.

Thanks

ajj3085 replied on Wednesday, January 24, 2007

albator:
I think there are legitimate reasons to save multiple root objects in the same transaction although I admit it is the first time we have to deal with an ERLB.


By definition (the definition the framwork is built around) a root object can be saved by itself, independately of other root objects.  It may be a parent object as well.  Check out page 120 of the C# 2005 edition of Rocky's book.

Also from the definition of a root object is that a root object defines the scope of a transaction; that is, the root, and any children will be updated within their own transaction.  Rocky has posted here about that before. 

That's the reason you're not getting the behavior you desire with ERLB.  The framework, because it is built on the concept that a root object updates in its own isolated transaction, won't support what you want.  You'll either have to redesign your objects so that there is one root, and the other's become children which can participate in the root objects transaction, or modify the framework by making the changes to ERLB to remove the behavior you find undesirable.

In the long run the first option is probably the best, unless you're willing to spend more time maintaining  your own version of Csla.  While you certainly can do that, the more customization you do of the framework, the more effort you'll spend moving to newer versions of the framework. 

It depends on how you see Csla.  Is it a starting point for you to modify and tweak to get your own custom framework, or is it more like a component library you'd purchase and cannot modify?  If Csla were a commercial project, option 2 wouldn't even likely be available, because you wouldn't have the source at all.

RockfordLhotka replied on Wednesday, January 24, 2007

You are trying to do something outside the design parameters for ERLB.

It seems that you have at least two options.

One is to override SaveItem(). I made this method virtual/Overridable primarily with the idea that you could add validation logic, but there's no reason you couldn't entirely override it to do some other type of update operation.

Another is to copy ERLB and use it as a base to make your own, where the save operation isn't handled by the collection itself, but perhaps the collection raises an event so the UI can initiate the save as it sees fit.

Of the two, I think I'd do the first option. Just make sure you handle the edit level properly - which probably means copying the existing SaveItem() code from ERLB and replacing the call to the Save() method with your alternate code.

Copyright (c) Marimer LLC