Changing parent loses child objects

Changing parent loses child objects

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


TheSquirrelKing posted on Monday, February 04, 2008

Hello,

I've got an object setup that involves a BuisinessBase child object that contains a collection of BusinessBase child objects, which, in turn, contains another collection of  BuisinessBase child objects. In simplified form, the hierarchy looks something like this:

Parent

Child

GrandChild

The problem I'm running into is that if I remove the Child object from one Parent, add it to another and then save, the Child object updates itself to reflect its new parent but the GrandChild objects associated with the Child end up being deleted.

I've tried a number of methods of getting this to work properly, but am having no luck so far. Can anyone suggest a solution to this that doesn't involve breaking the framework?

Thanks.

TheSquirrelKing replied on Tuesday, February 05, 2008

I hate to unabashedly bump my own post, so I'll try putting this another way: Does anyone have any working examples of being able to change the parent of a child object while still maintaining the child's children after a save? It would be pretty helpful to know if anyone else has run into this problem or if it is just me.

Thank you!

ajj3085 replied on Tuesday, February 05, 2008

Are your grandchildren being moved to the deleted list?  I think it may be because you remove the item from the inital list, which marks the isntance as deleted.. that may also be doign the same to its grandchildren.  

SomeGuy replied on Tuesday, February 05, 2008

You probably will have to make a copy of the Child (and it's children) and add the copy to the new Parent, while deleting the first Child.

Assuming that the Parent ID is part of the key for the Child, you probably don't want to 'Edit' it anyway. You will run into problems if you ever do replication etc.

 

TheSquirrelKing replied on Tuesday, February 05, 2008

The frustrating part of all this was that no matter how many different ways I tried cloning the child objects, removing the original from the old parent, and adding the clone to the new parent (or any variation on this order), I could not get the children to point to their new parent ID and have the grandchildren end up in the DB after a save. and After trying several additional methods of getting my child objects from one parent to another, I noticed some inconsistencies in the results I was getting (like the child objects apparently also disappearing from the DB or just not updating their parent ID value there). On a bit of a whim, I tried forcing the update of the parent ID when I add a child to a new parent:

newParent.Children.Add(childInstance)
childInstance.Update(newParent)
...
oldParent.Children.clear()
_parents = nothing

At this point I am able to call a save and get the expected results.

Note the bit where I set _parents to nothing. This is integral to making this work thanks to the additional complexity lazy loading throws into the mix.

Now, after fighting with this issue since Friday, I'm happy I can do something that makes things happen the way they're expected to. However, this solution gives me some pause as it feels a bit hacky (this is going to be a lot of calls to the Update proc and amounts to making an end-run around the DP's Save functionality for part of this operation).

Anyone care to comment or add any other particularly insightful ideas to the mix? I think I've been looking at this for too long.

SomeGuy replied on Tuesday, February 05, 2008

Hmmm. Depending on how you did your Clone (deep or shallow) and if it cloned Object State (IsNew, IsDirty). That could be your problem. What you needed was a 'New' child object with all 'New' GrandChildren since all the old ones are going be deleted.

Effectively:

oldChild = oldParent.Children[childId];
Child newChild = Child.NewChild(oldChild); // Implement a deep copy inside the Factory Method or ctor

//or copy the properties and GrandChildren manually
newChild.Prop1 = oldChild.Prop1; // etc.
foreach(GrandChild item in oldChild.GrandChildren)
   newChild.GrandChildren.Add(GrandChild.NewGrandChild(item)); // Again deep copy in GrandChild or do it manually

newParent.Children.Add(newChild);
newParent.Save();
oldParent.Children.Remove(childId);
oldParent.Save();

 

Copyright (c) Marimer LLC