1

親ノードを削除するとすべての子ノードが自動的に削除されるように、リストをツリーに変換することは可能ですか?

この理由は、再帰的なカテゴリがあり、子カテゴリを除くすべてのカテゴリを (再帰的に) 表示したいためです。

このシナリオでわかるように、赤いノードを削除すると、すべての緑のノードが自動的に削除されます。私のオプションは何ですか?

木

違いがある場合は、これが私が使用しているモデルです。

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);。これにより、現在のカテゴリが削除されます (図では赤いカテゴリが削除されます) が、緑色のカテゴリは残ります。

赤いものを削除すると、緑のものも削除されるようにするにはどうすればよいですか?

最後に、写真のすべての黒いアイテムのリストが必要です。

4

2 に答える 2

1

アイテムを削除するには、各アイテムを個別に削除する必要があります。それがdbコンテキストの仕組みです。ただし、すべてのアイテムを簡単に削除できます。ツリーをトラバースする単純なアルゴリズムは次のとおりです。

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;
}
于 2013-06-28T19:33:59.610 に答える
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;
}
于 2013-06-29T12:04:56.597 に答える