正在获取树层次结构中的最后一项

本文关键字:一项 最后 获取 层次结构 | 更新日期: 2023-09-27 18:29:01

我有一个支持多级层次结构的菜单。我创建了一个函数来获取树中的最后一个项目并返回其id。我需要这个id,这样我就可以在管理页面上隐藏向下移动的箭头。

虽然这很有效,但我花了两天时间试图找到一种LINQ方法来做同样的事情。所以我的问题是:

-有可能以一种纯粹的LINQ方式做到这一点吗?-如果是,如何?

我的MenuItem模型如下:

public partial class MenuItem
{
    public MenuItem()
    {
        this.ChildMenuItems = new HashSet<MenuItem>();
    }
    public int Id { get; set; }
    public int MenuItemTypeId { get; set; }
    public int MenuId { get; set; }
    public string DisplayText { get; set; }
    public string Controller { get; set; }
    public string Action { get; set; }
    public Nullable<int> ParentMenuItemId { get; set; }
    public int Rank { get; set; }
    public virtual MenuItemType MenuItemType { get; set; }
    public virtual Menu Menu { get; set; }
    public virtual ICollection<MenuItem> ChildMenuItems { get; set; }
    public virtual MenuItem ParentMenuItem { get; set; }
}

我的递归函数是这样的:

public static int GetLastMenuItemId(List<MenuItem> menuItems)
{
    foreach (MenuItem menuItem in menuItems.OrderBy(mi => mi.Rank))
    {                
        lastId = menuItem.Id;
        if (menuItem.ChildMenuItems.Any())
        {
            GetLastMenuItemId(menuItem.ChildMenuItems.ToList());
        }
    }
    return lastId;
}

此外,我的菜单树目前看起来是这样的:

Categories: 8 Parent: n/a
Admin: 1 Parent: n/a
    Manage Menus: 2 Parent: 1
        Manage Menus: 7 Parent: 2
        ------------: 5 Parent: 2
        Menus: 3 Parent: 2
        Menu Item Types: 4 Parent: 2
        Menu Items: 6 Parent: 2
    Manage Categories: 9 Parent: 1
    Manage Clicks: 10 Parent: 1
    Manage Comments: 11 Parent: 1
    Manage Images: 12 Parent: 1
    Manage Ratings: 13 Parent: 1

正在获取树层次结构中的最后一项

我会在MenuItem类中添加一个函数,用于检查当前MenuItem在父MenuItem的子MenuItems集合中的位置。

public List<MenuItem> FlattenedChildNodes {
  get {
    var ret = new List<MenuItem>();
    foreach (var item in ChildMenuItems) {
       ret.Add(item);
       if(item.ChildMenuItems != null) {
          ret.AddRange(item.FlattenedChildNodes);
       }
    }
    return ret;
  }
}  

public bool IsLastChild {
      get {
        if (ParentMenuItem == null) // return false if we have no parent (it's the root node)
           return false;
        else // return true iff we're the last child in the parent's collection of children
           return (ParentMenuItem.FlattenedChildNodes.ToList().IndexOf(this) == (ParentMenuItem.FlattenedChildNodes.ToList().Count - 1));
      }
    }