简体   繁体   中英

Deleting all children of object with parent/child relationship

I have this table in my SQL database:

Folders
-----------
FolderID
Name
ParentFolderID

I have a foreign-key relationship between ParentFolderID and FolderID so that it creates a parent/child relationship.

When I delete a folder, I'd like it to delete all child folders as well. I couldn't set the relationship to have a cascade delete because apparently SQL Server doesn't allow that on a relationship like this. But I'm using Entity Framework to create my classes based on these tables, so I plan on just doing it in my code.

I tried doing this with just a recursive method:

protected void DeleteUserFolder(UserFolder userFolder)
{
    if (userFolder.ChildFolders.Count.Equals(0))
    {
        _entities.UserFolders.Remove(userFolder);
        _entities.SaveChanges();
    }
    else
    {
        foreach (UserFolder childFolder in userFolder.ChildFolders.ToList())
        {
            DeleteUserFolder(childFolder);
        }
    }
}

It's not working as expected though, it only deletes about half my folders.

For instance, I had one parent folder named Test. Test had two child folders, Test2 and Test3. Test2 also had two child folders. I tried to delete Test, but it only deleted Test3 and the child folders in Test2.

Am I doing something wrong in this code? Or is there a better way to do this?

We can actually create a generic method that can fully traverse any tree based structure easily enough:

public static IEnumerable<T> Traverse<T>(T item, 
    Func<T, IEnumerable<T>> childSelector)
{
    var stack = new Stack<T>();
    stack.Push(item);
    while (stack.Any())
    {
        var next = stack.Pop();
        yield return next;
        foreach (var child in childSelector(next))
            stack.Push(child);
    }
}

Now we can just call that using your data:

foreach(var folder in Traverse(userFolder, f => f.ChildFolders))
    _entities.UserFolders.Remove(folder);
_entities.SaveChanges();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM