2016-05-21 4 views
0

Я пытаюсь получить всех детей 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(); 
} 

ответ

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

Ваш код должен работать. Вы должны получить первый уровень из метода FindByIncluding, но свойство Children также должно быть загружено.

Если вы хотите вернуть все MenuItems в одной коллекции, вы должны использовать что-то вроде этого:

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; 
      } 
     } 
    } 
} 

Теперь вы можете получить все MenuItems в одной коллекции по телефону:

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; 
} 
Смежные вопросы