What I personally do for direct deletion is that my delete stored procs also delete all children (and all their children, etc) first. That way only one call to the database is made for a direct delete. While this may seem like a maintenance PITA for the stored procs (they need to know about all data in objects below them), all mine are generated anyway so I don't even notice.
For deletion through the Save method my stored procs do the same thing though they take a timestamp as a parameter for concurrency (concurrency is ignored for any children/grandchildren). Then the update/Insert/Delete dataportal calls are not cascaded into any of the deleted object's children because it is not necessary, as everything has been deleted and no child of a deleted parent is valid to save.
I'm sure you will hear other ways to handle this, but this is my method. It works and it performs well.
Thanks,
Kevin
Typically when you delete a Root with children you are given the PK of the Root.
Based on this, I code gen DP_Delete like this:
Protected
Overrides Sub DataPortal_Delete(ByVal criteria As Object)PostDeleteData(tr)
Me.EndTransaction(tr) Catch ex As ExceptionThen in my hand written classes I can override DeleteChildren and use the Root PK value to help with the coding.
I also have the option of overriding PostDeleteData to take action once the delete has occurred.
Joe
James,
I understand. I too was disinclined to do the same thing for a long time due to:
1) Complexity of the delete and fetch procs knowing about their children/grandchildren/great grandchildren, etc. Hard to read, hard to maintain.
2) What if I want to reuse a class in a different hierarchy?
What I noticed over time is:
1) That I generated my classes and stored procs almost exclusively. Mostly any overrides were made to business logic. Very rarely did I ever override a stored proc. In addition, once I had the generator stabilized, I almost never looked at the darn things; they just worked.
2) I never took a class and moved it around from one hierarchy to another. Outside of issues around it being a questionable design practice, I just never had a need to do it.
3) On a complex object hierarchy I could find myself easily making 100 calls to the DB to do a fetch or delete operation. It just seemed so unneeded and wasteful.
In the end I converted the generator to make centralized fetch and delete procs. You're not really coding the object hierarchy into the stored procs, just recognizing the data key relationships that you are probably already enforcing due to referential integrity anyway. If I could figure out a simple and understandable method to send all the data for an object hierarchy to the insert and update procs, I would do those the same way too. But alas, not yet.
No, I have no place to serialize it all into XML to tear it apart on the other side or storing it as XML in SQL Server 2005's XML data type so I can do single update/insert procs. Not yet anyway.
Your mileage may vary.
Thanks,
Kevin
Joe: in which class is your code, above? presumably you do the physical deletion in DeleteChildren, rather than via MyRootObject.Save() ?
Thanks
James.
====================================================================
The code is in the Root BO.
DeleteChildren method runs code like:
Dim parentkey
As Integer = crit.KeyExecuteNonQuery(tr, CommandType.Text, MyChildSQL.DeleteByParentKey(parentkey ))
Joe
Copyright (c) Marimer LLC