2016-11-21 66 views
5

我有一個小菜單,我想通過數據庫表中的id類似下面的命令:順序菜單節點

public class Obj 
    { 
     public string Value { get; set; } 
     public int? ParentNodeId { get; set; } 
     public int? PreviousNodeId { get; set; } 
     public int? NextNodeId { get; set; } 
    } 

private IEnumerable<MenuNodeDTO> GetSortedMenuNodes(int menuId) 
    { 
     var nodes = LoadMenuNodes(menuId); 
     foreach (MenuNode menuNode in nodes 
      .Where(s => s.MenuItemId == null && s.ParentNodeId == null) 
      .OrderBy(x => x?.PreviousNodeId) 
      .Where(x => x.PreviousNodeId != x.Id)) 
     { 
      MenuNodeDTO tmpMenuNode = new MenuNodeDTO(); 
      tmpMenuNode.MenuNodeDtoId = menuNode.Id; 
      tmpMenuNode.MenuItemCode = menuNode.MenuItem?.Code; 
      tmpMenuNode.ChildMenuNodes = GetChildNodes(menuNode).ToList(); 
      tmpMenuNode.MenuSettings = GetMenuSettings(menuNode).ToList(); 
      yield return tmpMenuNode; 
     } 
} 

例子:

Id = 1 MainMenuPoint1 ParentNodeId = null, PreviousNodeId = null, NextNodeId = 4 
Id = 2 -> 1 ChildNodeFromPoint1 ParentNodeId = 1, PreviousNodeId = null, NextNodeId = null 
Id = 3 --> ChildNodeFromFirstChildNode1 ParentNodeId = 2, PreviousNodeId = null, NextNodeId = null 
Id = 4 MainMenuPoint2 ParentNodeId = null, PreviousNodeId = 1, NextNodeId = null 

與我的每個問題是,當id改變了排序不起作用。 有人知道如何通過parentid,previousid和next id命令來檢查每次所有關係的ID嗎?

+1

至於我,我會建議另一個數據庫結構:'ParentNodeId'和'Order'。你可以使用DFS來訂購你的節點,並且可以使用Order來訂購葉子。順序也不能保證是明顯的,節點1的所有子項都可以有順序= 0 - 這意味着它們應該按名稱\ ID \排序,無論如何,這並不重要。 –

+1

@YeldarKurmangaliyev問題在於當你改變菜單結構,移動節點或刪除節點時,你會怎麼做? –

+1

談論順序,移除或移動一個節點什麼也不會改變 - 它工作得很好。談到父母關係,如果它有子節點,你就無法刪除一個節點。這是數據完整性的問題。在刪除它之前,您需要清除其子節點列表。 –

回答

1
private IEnumerable<MenuNodeDTO> GetSortedNodes(Menu menu, MenuNode node) 
     { 
      List<MenuNodeDTO> items = new List<MenuNodeDTO>(); 

      var nodes = node != null ? node.ChildMenuNodes : menu.MenuNodes; 
      var nextNode = node == null 
       ? nodes.Where(c => c.PreviousNodeId == null && c.ParentNodeId == null).FirstOrDefault() 
       : nodes.Where(c => c.ParentNodeId == node.Id && c.PreviousNodeId == null).FirstOrDefault(); 

      while (nextNode != null) 
      { 
       MenuNodeDTO tmpMenuNode = new MenuNodeDTO(); 
       tmpMenuNode.MenuNodeDtoId = nextNode.Id; 
       tmpMenuNode.MenuItemCode = nextNode?.MenuItem?.Code; 
       tmpMenuNode.ChildMenuNodes = this.GetSortedNodes(menu, nextNode).ToList(); 
       tmpMenuNode.MenuSettings = GetMenuSettings(nextNode).ToList(); 
       items.Add(tmpMenuNode); 
       if (!nextNode.NextNodeId.HasValue) break; 
       nextNode = nextNode.NextNode; 
      } 
      return items; 
     }