C# 按父级、上一个和下一个id排序菜单节点
我有一个小菜单,我想按DB表id订购,如下所示:C# 按父级、上一个和下一个id排序菜单节点,c#,C#,我有一个小菜单,我想按DB表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 I
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;
}
}
my for each的问题是,当id更改时,排序不起作用。
有人知道如何按parentid、previousid和next id排序,每次检查关系的所有id吗 private IEnumerable GetSortedNodes(菜单,菜单节点)
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;
}
{
列表项=新列表();
var nodes=node!=null?node.ChildMenuNodes:menu.MenuNodes;
var nextNode=node==null
?节点。其中(c=>c.PreviousNodeId==null&&c.ParentNodeId==null)。FirstOrDefault()
:nodes.Where(c=>c.ParentNodeId==node.Id&&c.PreviousNodeId==null);
while(nextNode!=null)
{
MenuNodeTo tmpMenuNode=新建MenuNodeTo();
tmpMenuNode.menunodeToId=nextNode.Id;
tmpMenuNode.MenuItemCode=nextNode?MenuItem?代码;
tmpMenuNode.ChildMenuNodes=this.GetSortedNodes(menu,nextNode.ToList();
tmpmenuode.MenuSettings=GetMenuSettings(nextNode.ToList();
items.Add(tmpMenuNode);
如果(!nextNode.NextNodeId.HasValue)中断;
nextNode=nextNode.nextNode;
}
退货项目;
}
至于我,我建议另一种数据库结构:ParentNodeId
和Order
。您可以使用DFS对节点进行排序,并使用order
对叶子进行排序。顺序也不应保证是不同的,节点1的所有子项的顺序都可以为0-这意味着它们应该按名称\ID\或其他任何东西排序,这无关紧要。@YeldarKurmangaliyev问题是,当您更改菜单结构、移动节点或删除节点时,您会怎么做?谈论顺序,删除或移动节点不会改变任何东西——它工作得很好。谈到父关系,如果节点有子节点,则无法删除该节点。这就是数据完整性的问题。在删除它之前,需要清除它的子节点列表。
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;
}