One Child Object to be used on Many Parent Objects

One Child Object to be used on Many Parent Objects

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


sutono posted on Monday, March 07, 2011

Hi Experts,

 

i've got problems on designing child object. As you see that i got a child object that is going to be used by many parent objects.

This is my example code

 

public class ParentA : BusinessBase<ParentA>

{

private static PropertyInfo<ChildList> _TablesProperty = RegisterProperty<ChildList>(p => p.Tables);

        public ChildX Tables

        {

            get

            {

                if (!(FieldManager.FieldExists(_TablesProperty)))

                    LoadProperty(_TablesProperty, ChildX.NewChild());

                return GetProperty(_TablesProperty);

            }

        }

 

}

 

and this is the code for Child Object

public class ChildX: BusinessBase<ChildX>

{

 

private void Child_Insert(ParentA parent)

        {

            using (var ctx = ContextManager<DataAccess.MyDataContext>.GetManager(DataAccess.Database.MyDatabase))

            {

                LoadProperty(_EntityIdProperty, parent.entityId);

                ctx.DataContext.sp_AddChild(entityId, childId, code, description, dateCreated);

            }

        }

 

}

 

Well actually this code is i copied from ProjectTracker sample project. But from this code the object ChildX is the child object of to the object ParentA. My case is i got another root object (ParentB) which is using ChildX as the child object also. From the dataaccess of its child object already fixed to the ParentA as the root object ("private void Child_Insert(ParentA parent)") so what should i do? can i create the ChildXA and ChildXB that is inherited from object ChildX, so i dont need to re-code the BusinessMethod, AuthenticationRules. I've tested but failed. Maybe because of my lack experience on CSLA.

Thats why i'm asking help from you experts... Please tell me your suggestion of my case.. and maybe write some sample code (that's going to help me alot).

Thx a lot, i need it very urgent

rgds,

Stone

RockfordLhotka replied on Monday, March 07, 2011

There is no existing CSLA base class that supports an editable child that is contained by more than one parent at a time.

The Parent property, along with ChildChanged events, and persistence of the object graph all rely on an object being part of exactly one object graph and having exactly one parent.

JonnyBee replied on Monday, March 07, 2011

You could however have a property of type ChildX on both ParentA and ParentB but you cannot move or use the same instance in both parents.

In order to do this then ChildX should have no reference to any parent type. If you need the parent ID then send it as a data value and not the parent object in Child_Insert/Child_Update

 

RockfordLhotka replied on Monday, March 07, 2011

It is also critically important to not confuse a using relationship with a containment relationship.

Parent-child is a containment relationship. The child is literally part of the parent. The state of the parent includes its children. In the physical world (outside of maybe some wierd quantum physics) any given thing (particle, atom, molocule, crystal, structure, etc) only exists within one container - it is only part of one thing. Objects are just like that.

(of course now that I've laid down that gauntlet, I'm sure some chemist or physist will prove me wrong :) )

But in the real world things use other things. I am using a keyboard right now. It is not part of me, I don't contain it. But I am using it. Objects are like that too.

In almost every case where an object instance appears to be contained by two objects, the problem is just a misunderstanding of the problem that has led to an incorrect object model. Just consider the real relationships between the objects within the context of the use case or user scenario you are trying to solve.

sutono replied on Tuesday, March 08, 2011

Hi thanks for your quick reply experts... Sorry i'm quite busy yesterday to reply.

i'm so happy to get the reply so quickly from 2 experts especially from Rocky Smile

Yes i'm agree with JonnyBee, i cleared the reference to parent type on child object's data access. I'd done a little change on my parent object's business method and my child object's factory method and data access. Please take a look at my code...

Code from Parent Object

 

private static PropertyInfo<PDCVariable> _PDCVariableProperty = RegisterProperty<PDCVariable>(p => p.PDCVariable);

        public PDCVariable PDCVariable

        {

            get

            {

                if (!(FieldManager.FieldExists(_PDCVariableProperty)))

                    LoadProperty(_PDCVariableProperty, PDCVariable.New(F_EntityId));

                return GetProperty(_PDCVariableProperty);

            }

        }

 

so i put in the value that i want to pass in into child object by the first declare object into property when the value on its property is null

Code in my child object :

internal static PDCVariable New(Guid entityId)

        {

            return DataPortal.CreateChild<PDCVariable>(entityId);

        }

private void Child_Create(Guid entityId)

        {

            LoadProperty(_EntityIdProperty, entityId);

            LoadProperty(_DateCreatedProperty, new SmartDate(System.DateTime.Now));

            LoadProperty(_IdProperty, Guid.NewGuid());

        }

 

So in this case, this child object can be used by many parent object as in every business method on parent object must passing the value (entityId) into child object. I'm wondering whether this method if true or not, so i'm just writing my code here... asking for expert's suggestion :D

Please give me some suggestion or idea for this.

 

NB for Rocky:

Hi Rocky, for your 2nd reply about the real relationships between objects within the context of user scenario that i'm trying to solve. Well my user case is like  that :

 in manufacturing company, usually they will create a spec. (for example Spec Finish Goods) and within this spec. they'll need many specification of different materials in order to finish this spec. Lets say that in Spec Finish Goods, we're going to have Spec Materials Foil, Spec Materials Inner Frame, etc. So automatically Spec Finish Goods will be the parent object which is containing Spec Material Foil, Spec Material Inner Frame, and many more.
 So how if i got another spec. (for example Spec Cigarette) which is containing Spec Material Foil also. So i'm wondering if i create a child object SpecMaterialFoil which is will be used by 2 parent object Spec Cigarette and Spec Finish Goods.

Thats my user case. Hopefully i didnt type wrong, cause my english is quite bad.

Well thanks for your reply

Stone

Charleh replied on Wednesday, March 09, 2011

Just clarifying my understanding - but I have a child business list class which is used by multiple parents by interface which works fine

Is the issue whether a child should be contained by multiple parents simultaneously? I can't see a problem with having multiple parents use the same child as a business object platform and it works well in the project I'm running - but I can't see a place where a child instance contained by multiple parents simultaneously would be a good idea

RockfordLhotka replied on Wednesday, March 09, 2011

A child can be used by multiple parents, just not at the same time. An editable child can have exactly one parent at any one time.

This is because the child is literally part of the parent. N-level undo, data binding, persistence, serialization, ChildChanged eventing - all these things rely on an object being part of one object graph and having one parent.

Other objects and object graphs can have a reference to the same object, as long as that reference is NonSerialized and NotUndoable. That is a using relationship, not a containment relationship.

If your app is "working" with a child being contained by more than one parent, then that's just failure waiting to happen, and you haven't hit the failure conditions yet.

Charleh replied on Wednesday, March 09, 2011

Hi Rocky, yes that's what I thought - I didn't expect that having a child instance contained in multiple parent instances would work as CLSA would need a lot of supporting code to track multiple parent refs - I wanted to clear up any confusion as I think with this thread it's easy to get mixed up between multiple parents in a relationship context and multiple parents in an object containment context

My objects only have a relationship that allows a child BO class to be used by any other class - the actual object instances are contained only within the parent that owns them

e.g. a standard collection of notes which can be reused on a sales order, customer, invoice etc

sutono replied on Wednesday, March 09, 2011

Hi Charleh,

Thx for your feedback, of course my child object wont be obtained by multiple parent object at the same time. So my method i think still can work as you had tried. Thx a lot for your sharing experience :)

Btw i got another question...
How if my parent object contain an editable child list object, and from this editable child list object i need to have another editable child object and this editable child object also got a list of editable child list object? 

 If i draw is like that :

Parent --> Editable Child List Object (ChildA) --> Editable Child Object (ChildB) --> Editable Child List Object.(ChildC)

i cant upload my object diagram image here, so this is the brief of my business flow i'm handling now.  i'm quite stress to get a business flow like that.

Do i have to create ChildB as a Editable Switchable Object? as the childB is either Parent of the ChildC and also child object of ChildA also.
Or all ChildA, ChildB, ChildC i declare as the child object? Can it save all data at the same time after UI used the Parent object method Save() ?

Please guide me.... Thx :) 

Charleh replied on Thursday, March 10, 2011

A, B and C should be children - and you can save from the Parent which will cascade the save down to the dirty children

Editable switchable is for a scenario where you need a child that can belong to a parent, or can have no parent: e.g.

Parent.GetParent() = Parent -> EditableSwitchable (child)

or

EditableSwitchable.GetEditableSwitchable() = EditableSwitchable (root)

I don't think this is recommended

What's your use case? What will your objects be - it depends on what editing you need to allow at each level of the object graph and how far you want to support edit/undo

If you have a large object graph which will be edited on many screens, you need to decide whether you want to support a scenario such as:

edit parent -> edit child -> edit child of child -> oops I did something wrong..undo everything

You can always use 'save' to update the object when a user saves on a child edit screen, but bear in mind that the whole object will need to be valid for the save to work and it will need to be saved from the parent

sutono replied on Thursday, March 10, 2011

well from your explanation i dont think i need switchable object anymore. i'll try out to have child A, B and C 1st and c how its going....

Thx a lot Charleh...  That helps me a lot...

Thanks also to Rocky and JonnyBee

Stone :)

Copyright (c) Marimer LLC