使用父/子关系删除对象的所有子项

时间:2014-01-14 22:22:02

标签: c# asp.net entity-framework

我在SQL数据库中有这个表:

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

我在ParentFolderIDFolderID之间建立了外键关系,以便创建父/子关系。

当我删除文件夹时,我希望它也删除所有子文件夹。我无法将关系设置为级联删除,因为显然SQL Server不允许这样的关系。但我正在使用Entity Framework基于这些表创建我的类,所以我打算在我的代码中执行它。

我尝试使用递归方法执行此操作:

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);
        }
    }
}

虽然它没有按预期工作,但它只删除了我文件夹的一半。

例如,我有一个名为Test的父文件夹。 Test有两个子文件夹,Test2和Test3。 Test2还有两个子文件夹。我试图删除Test,但它只删除了Test3中的Test3和子文件夹。

我在这段代码中做错了什么?或者有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

我们实际上可以创建一个通用方法,可以很容易地完全遍历任何基于树的结构:

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);
    }
}

现在我们可以使用您的数据来调用它:

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