递归获取所有子 class
getting all sub class recursively
我正在尝试获取所有 children MenuItems
子 children 直到结束,但此代码仅获取第一级。
如何转换此代码以管理该功能?
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();
}
你必须使用递归。
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);
这将获取所有子项、子项的子项等等,直到您检索到所有子项。
您的代码应该可以工作。您应该从 FindByIncluding 方法获得第一级,但也应该加载 Children 属性。
如果你想 return 一个集合中的所有菜单项,你应该使用这样的东西:
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;
}
}
}
}
现在您可以调用一个集合中的所有菜单项:
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;
}
我正在尝试获取所有 children MenuItems
子 children 直到结束,但此代码仅获取第一级。
如何转换此代码以管理该功能?
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();
}
你必须使用递归。
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);
这将获取所有子项、子项的子项等等,直到您检索到所有子项。
您的代码应该可以工作。您应该从 FindByIncluding 方法获得第一级,但也应该加载 Children 属性。
如果你想 return 一个集合中的所有菜单项,你应该使用这样的东西:
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;
}
}
}
}
现在您可以调用一个集合中的所有菜单项:
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;
}