递归获取所有子类

时间:2016-05-21 22:11:47

标签: c# repository-pattern

我试图让所有的孩子MenuItems与子孩子一起直到结束,但这段代码只获得第一级。

如何转换此代码以管理该功能?

public class MenuItem : IEntityBase
{
    public int Id { get; set; }
    public string Text { get; set; }
    public virtual ICollection<MenuItem> Children { get; set; }
    public virtual MenuItem Parent { get; set; }
    public bool onMenu { get; set; }

    public MenuItem()
    {
        Children = new List<MenuItem>();
    }
}

IEnumerable<Entity.MenuItem> _menuItemList = _menuItemRepository.FindByIncluding(x => x.Parent == null && x.onMenu == true, t => t.Children);

public virtual IEnumerable<T> FindByIncluding(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includeProperties)
{
    IQueryable<T> query = _context.Set<T>();
    foreach (var includeProperty in includeProperties)
    {
        query = query.Include(includeProperty);
        query = query.Where(predicate);
    }
    return query.AsEnumerable();
}

2 个答案:

答案 0 :(得分:1)

你必须使用递归。

public List<MenuItem> GetItems (MenuItem item) {
    var items = item.Children;

    for (var i=0; i<item.Children.Count; i++) {
        var child = item.Children[i];
        items.AddRange(GetItems(child));
    }

    return items;
}

var allItems = GetItems(yourMainItem);

这将让所有孩子,孩子的孩子等等,直到你找回所有孩子。

答案 1 :(得分:1)

您的代码应该有效。你应该从FindByIncluding方法获得第一级,但也应该加载Children属性。

如果要在一个集合中返回所有MenuItem,则应使用以下内容:

public class MenuItem : IEntityBase
{
    //Rest of your code goes here

    public IEnumerable<MenuItem> GetDescendants(bool includeItself = true)
    {
        if (includeItself)
        {
            yield return this;
        }

        foreach (MenuItem menuItem in this.Children)
        {
            foreach (MenuItem descendant in menuItem.GetDescendants(includeItself: true))
            {
                yield return descendant;
            }
        }
    }
}

现在,您可以通过调用:

获取一个集合中的所有MenuItem
IEnumerable<Entity.MenuItem> _menuItemList = _menuItemRepository.FindByIncluding(x => x.Parent == null && x.onMenu == true, t => t.Children);
IEnumerable<Entity.MenuItem> _allItems = GetAllMenuItems(_menuItemList);

public IEnumerable<MenuItem> GetAllMenuItems(IEnumerable<MenuItem> rootMenuItems)
{
    IEnumerable<MenuItem> result = rootMenuItems;

    foreach (MenuItem menuItem in rootMenuItems)
    {
        result = result.Concat(menuItem.GetDescendants(false))
    }

    return result;
}