Need to do a deferred delete all children in one statement

Need to do a deferred delete all children in one statement

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


j055 posted on Monday, February 08, 2010

Hi

I have a root object with a child collection. Sometimes I need to delete all the children when the root object is saved. Normally each Child_DeleteSelf is called for each item in the DeletedList but if I've called a method on the list like:

public void RemoveAll()
{
    Clear();
}

I'd like to call a single stored proc instead of a one proc for each item when I call Save on the root.

Is there a way to easily adapt the child collection to do this?

Thanks
Andrew

 

RockfordLhotka replied on Monday, February 08, 2010

Sure, just override the collection's Child_Update() method and call your DAL from there. Don't echo the call to the child objects in DeletedList - just clear the DeletedList and you should be set.

j055 replied on Tuesday, February 09, 2010

Thanks for your suggestion. Adopted this approach. 

        private void Child_Update()
        {
            RaiseListChangedEvents = false;

            if (Count == 0 && DeletedList.Count > 0)
            {
                  // call a stored proc to delete using a foreign key.

                  // is this necessary? doesn't seem to do any harm
                DeletedList.Clear();
            }
            else
            {
                // otherwise do the normal deletes
                Child_Update();
            }

            RaiseListChangedEvents = true;
        }

Cheers

Andrew

RockfordLhotka replied on Tuesday, February 09, 2010

Is DeletedList.Clear() necessary? Yes. If you don't clear the list, then Child_Update() will call Child_DeleteSelf() on each of those child objects, which seems like a bit of a waste, and forces you to implement the method in that class, even though that method won't actually do anything.

rxelizondo replied on Tuesday, February 09, 2010

The solution to your problem looks fine but I think you are walking a fine line here (at least in my opinion).

Manually clearing the DeletedList collection seems risky to me, such task is something that the CSLA is normally charged with doing and its best to leave that task to the CSLA itself (again this is just my opinion).

The fact that you are sometimes bypassing the standard Child_Update() code is simply creating more maintenance issues. I mean, what’s going to happen if Rocky updates that function later to fix a bug or enhance it? Perhaps then your DeletedList clearout wont work anymore the way you have it becuase there must be some other steps that must happen before you do that.... I mean, who knows.

But if you want to go that way, I would change your code a little to something like this:

Don’t thing you need to worry about the “RaiseListChangedEvents” since you are only cleareing the DeleteList wich is property and not the collection itself.

 protected override void Child_Update(params object[] parameters)
{
    if (Count == 0 && DeletedList.Count > 0)
    {
        // call a stored proc to delete using a foreign key.

        DeletedList.Clear();
    }
    else
    {
        base.Child_Update(parameters);
    }
}

 

xAvailx replied on Monday, February 08, 2010

Another option is to let the database do the deleting for you by setting your foreign keys with cascade delete.

rxelizondo replied on Monday, February 08, 2010

 

If you don’t want to mess around with the CSLA metadata (I personally wouldn’t like to mess with it myself):

 

On my root object DataPortal_Update, I would do a count on the non deleted list and if the count is zero then that means all children have been deleted. If that was the case, I would run my database delete command to delete all the children in one shot from there.

 

I would then iterate through all deleted children on the DeletedList collection and set some DontRunDeleteCode flag to True on each of them. Once that’s done, I would continue with my normal call to FieldManager.UpdateChildren().

 

On the Child_DeleteSelf method, I would check for the DontRunDeleteCode value and if true I would simply exit the function. If the flag was true that would mean that deletion of the object was taken care by the parent.

 

That’s just me of course, like I said, I rather let the CSLA do its stuff and don’t mess around with its internal implementation such as clearing the DeletedList myself…. Oh boy, did I just imply that I don’t like Rocky’s suggestion…. I think I am in trouble Big Smile

 

Copyright (c) Marimer LLC