How should I transfer a Child from ParentA to ParentB ?

How should I transfer a Child from ParentA to ParentB ?

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


lukky posted on Tuesday, June 02, 2009

Hi all,

As the subject states, I'm trying to implement a method of transferring certain Child objects from a Parent to another one.

In the concrete, I want to transfer OrderDetails from one OrderHeader to another one. In the Database  OrderDetails table, it would simply be a matter of changing the OrderHeaderID of the selected OrderDetails rows, but to do it using BOs implies more I guess.

I want to avoid having to delete the OrderDetails and recreate them, as this would cause Triggers to be fired that would cause unwanted side-effect (those Triggers are used to insert/update/delete ProductionOrderDetails in a one-to-one fashion with OrderDetails, and we don't want to delete/insert them).

So, if anyone could suggest a way....

Thank you.

JoeFallon1 replied on Tuesday, June 02, 2009

I think you need to explain the use case a bit more. Because you don't say if you have both OrderHeader BOs in memory at the time you need to transfer the child BO. If neither is in memory then you just need a command object to do what you described as far as hitting the database an just changing the order detail row ID so it points to a different parent order hdr.

If both are in memory it may matter if they are both editable or if one of them is a read only collection.

So I think we need more information before we can provide solid advice.

Joe

lukky replied on Wednesday, June 03, 2009

Joe,

You are right. The problem is that I haven't decided yet on the exact use case, since I'd like to know if doing it with BOs is complicated.

Let's say I have the original Order BO in memory. I could simply use SPs to create a copy of the OrderHeader, and update the desired OrderDetails' FK to now point to the new OrderHeader. It would then be only a matter of reloading the BO. Simple enough.

On the other hand, let's say I have both BOs in memory, and that I pass a Child object between the two. Would I be able with minimum effort to treat this in such a way that it won't be sent back to the DB as both a delete and an insert ? If yes, then I might consider doing it "in memory".

Thanks for your time.


shawndewet replied on Wednesday, June 03, 2009

The CommandObject executing a change on the database would be the simplest; this obviously requires both order headers to exist at the time.

But it sounds like you are creating a new order header, and to get this new one into the DB for the CommandObject to work would of course require saving of this new order header first.  I don't know about your business rules, but ours typically do not allow the saving of an orderheader if there are no detail lines.  If you do have such a rule, you'd have to go the route of doing this "in memory".  Load up the "source" OrderHeader along with its DetailLine collection.  At this point, each detail line's IsDirty would be False, and the IsNew will be False.

Instantiate your new OrderHeader and set its properties as needed.  Then add to it's DetailLines collection the detail line objects from the "source" OrderHeader.  If at this point you call Save on the header, it won't also save the detail lines coz they're still "Clean".  The way to get them "dirty" for the save would be to set their FK property to the new order header's ID.  Of course if you're using database-assigned Identity fields here, you only know this new ID once you have saved the OrderHeader - in which case you can only set this property on the lines in the DataPortal_Insert of the header.  Even so, doing it then is fine, and this will still cause the detail lines to be "dirty";  the key though is that their IsNew is still False, causing the dataportal to Update them (instead of inserting them).  That's it for the new orderheader.

As for the "source" OrderHeader, if you have removed the the detail lines from it's DetailLines collection, you once again end up with an OrderHeader with no lines, so business rules would/could/should prevent you from saving it.  So I'd say here just call the static OrderHeader.DeleteOrderHeader(iPKToDelete) method, and then clear it from memory.  (This database code here would (should) delete from the OrderHeader table the PK, and then delete from the detail lines table for the same orderheader, but by then there are no detail lines matching the given key to delete, so no harm done).

Copyright (c) Marimer LLC