2013-06-28 236 views
1

是否可以将List转换为Tree,以便当我删除父节点时,所有子节点都将自动删除?将列表转换为树

这样做的原因是我有递归类别,我想显示除子类别(递归)以外的所有类别,而在我的脑海中最简单的方法是在图片中执行类似操作。

正如你在这个场景中看到的,当我删除红色节点时,所有绿色节点都会自动删除它们自己。我有什么选择?

Tree

这里是我使用的,如果这有什么差别模型。

public class Category 
{ 
    public int Id { get; set; } 

    public int? RootCategoryId { get; set; } 
    public virtual Category RootCategory { get; set; } 
    public virtual ICollection<Category> ChildCategories { get; set; } 
} 

这是我迄今为止

// This would eliminate only current category but not its children = bad 
var availableCategories = _db.Categories.Where(x => x.Id != currentlyEditedId); 

因此,举例来说,当我想编辑类别我会打电话_db.Categories.Where(x => x.Id != currentlyEditedId);。这将消除当前类别(在图片中它将删除红色),但是绿色的将保留。

我该如何确定如果我删除了红色的那个绿色的也会删除?

最后我想要列出图片中所有黑色项目。

+6

你有什么问题使用你刚刚显示的类别类? – Servy

+0

@Servy问题是他得到了递归树的类别,这是太多的数据,他想控制递归深度。 – skmasq

+2

@skmasq他从未这么说过。没有迹象表明数据的数量,或者深度太多而无法管理。 – Servy

回答

1

这就是我想要的。传入分类列表并删除当前分类并递归删除其所有子项。

/// <summary> 
/// Get list of all categories except current one as well as all it's child categories 
/// </summary> 
/// <param name="id">Current category id</param> 
/// <param name="categories">List of categories</param> 
/// <returns>List of categories</returns> 
public static List<Category> CategoriesWithoutChildren(int id, List<Category> categories) 
{ 
    var currentCategory = categories.Single(x => x.Id == id); 
    categories.Remove(currentCategory); 

    if (currentCategory.ChildCategories.Count > 0) 
    { 
     currentCategory.ChildCategories.ToList().ForEach(x => 
     { 
      categories = CategoriesWithoutChildren(x.Id, categories); 
     }); 
    } 

    return categories; 
} 
1

要删除一个项目,您需要逐个删除它们;这就是数据库环境的工作原理。尽管你可以简单地删除所有的项目。下面是简单的算法遍历树:

public static IEnumerable<Category> Traverse(Category root) 
{ 
    var stack = new Stack<Category>(); 

    stack.Push(root); 

    while (stack.Any()) 
    { 
     var next = stack.Pop(); 
     yield return next; 
     foreach (var child in next.ChildCategories) 
      stack.Push(child); 
    } 
} 

现在你可以这样做:

public static void DeleteCategory(Category category) 
{ 
    var items = Traverse(category).ToList(); 
    var itemsToDelete = _db.Categories.Where(cat => items.Contains(cat)); 
    //delete items 
} 

如果你不是只想删除一个项目从它在内存中的集合,而不是你只需要拨打Remove就可以了。如果你没有父母,和只需要删除的节点和根,那么你就需要有另外一种方法来遍历树:

public static bool Remove(Category root, int id) 
{ 
    var stack = new Stack<Category>(); 

    stack.Push(root); 

    while (stack.Any()) 
    { 
     var next = stack.Pop(); 
     foreach (var child in next.ChildCategories) 
     { 
      if (child.Id == id) 
      { 
       next.ChildCategories.Remove(child); 
       return true; 
      } 
      stack.Push(child); 
     } 
    } 

    return false; 
}