ASP.Net MVC:如何使用递归技术显示嵌套的父子关系

我只是尝试使用递归函数调用在剃刀中使用ulli显示第n个关系。 假设我有db表,我存储父子关系,如下所示。

表结构

 +----+----------+----------+ | ID | Name | ParentID | +----+----------+----------+ | 1 | Parent 1 | 0 | +----+----------+----------+ | 2 | child 1 | 1 | +----+----------+----------+ | 3 | child 2 | 1 | +----+----------+----------+ | 4 | child 3 | 1 | +----+----------+----------+ | 5 | Parent | 0 | +----+----------+----------+ | 6 | child 4 | 4 | +----+----------+----------+ 

所以我想在剃刀视图中以这种方式显示嵌套数据

 Parent 1 child 1 child 2 child 3 child 4 Parent 

所以这个代码我尝试但无法实现目标。

c#POCO课程

 public class MenuItem { public int Id { get; set; } public string Name { get; set; } public int ParentId { get; set; } public virtual ICollection Children { get; set; } } public class MenuDTO { public int Id { get; set; } public string Name { get; set; } public int ParentId { get; set; } public virtual ICollection Children { get; set; } } 

行动代码

  public ActionResult Index() { List allMenu = new List { new MenuItem {Id=1,Name="Parent 1", ParentId=0}, new MenuItem {Id=2,Name="child 1", ParentId=1}, new MenuItem {Id=3,Name="child 2", ParentId=1}, new MenuItem {Id=4,Name="child 3", ParentId=1}, new MenuItem {Id=5,Name="Parent 2", ParentId=0}, new MenuItem {Id=6,Name="child 4", ParentId=4} }; List mi = allMenu .Select(e => new { Id = e.Id, Name = e.Name, ParentId = e.ParentId, Children = allMenu.Where(x => x.ParentId == e.Id).ToList() }).ToList() .Select(p => new MenuDTO { Id = p.Id, Name = p.Name, ParentId = p.ParentId, Children = p.Children //Children = p.Children.Cast() }).ToList(); ViewBag.menusList = mi; return View(); } 

剃刀代码

 @{ var menuList = ViewBag.menusList as List; ShowTree(menuList); } @helper ShowTree(List menusList) { if (menusList != null) { foreach (var item in menusList) { 
  • @item.Name @if (item.Children.Any()) {
      @ShowTree(item.Children)
    }
  • } } }

    在我的情况下,我是查询列表allMenu来从db表获取数据。 当我运行我的代码然后我得到低于错误

    CS1502:’ASP._Page_Views_Menu_Index_cshtml.ShowTree(System.Collections.Generic.List)’的最佳重载方法匹配有一些无效的参数

    告诉我我的代码有什么问题。 请帮助我修复并获得我的目标。 谢谢

    编辑

    完整的工作代码如下

     @helper ShowTree(List menusList) { 
      @foreach (var item in menusList) {
    • @item.Name @if (item.Children!=null && item.Children.Any()) { @ShowTree(item.Children) }
    • }
    } @{ var menuList = ViewBag.menusList as List; @ShowTree(menuList); } public ActionResult Index() { List allMenu = new List { new MenuItem {Id=1,Name="Parent 1", ParentId=0}, new MenuItem {Id=2,Name="child 1", ParentId=1}, new MenuItem {Id=3,Name="child 2", ParentId=1}, new MenuItem {Id=4,Name="child 3", ParentId=1}, new MenuItem {Id=5,Name="Parent 2", ParentId=0}, new MenuItem {Id=6,Name="child 4", ParentId=4} }; List mi = allMenu .Where(e => e.ParentId == 0) /* grab only the root parent nodes */ .Select(e => new MenuItem { Id = e.Id, Name = e.Name, ParentId = e.ParentId, Children = allMenu.Where(x => x.ParentId == e.Id) /* grab second level children */ .Select(e2 => new MenuItem { Id = e2.Id, Name = e2.Name, ParentId = e2.ParentId, Children = allMenu.Where(x2 => x2.ParentId == e2.Id).ToList() /* grab third level children */ }).ToList() }).ToList(); ViewBag.menusList = mi; return View(); } public class MenuItem { public int Id { get; set; } public string Name { get; set; } public int ParentId { get; set; } public virtual List Children { get; set; } }

    您的代码无法找到一个函数ShowTree在执行该行时采用ICollection类型的参数

     @ShowTree(item.Children) 

    因为item.Children的类型为ICollection 。 代码中的函数ShowTree采用不同类型的参数List ,它与ICollection 。 因此,运行时会报告您看到的CS1502错误。

    在意识到您正在寻找递归解决方案之后,我已经修改了代码来做到这一点。

    行动守则

     public ActionResult Index() { List allMenu = new List { new MenuItem {Id=1,Name="Parent 1", ParentId=0}, new MenuItem {Id=2,Name="child 1", ParentId=1}, new MenuItem {Id=3,Name="child 2", ParentId=1}, new MenuItem {Id=4,Name="child 3", ParentId=1}, new MenuItem {Id=5,Name="Parent 2", ParentId=0}, new MenuItem {Id=6,Name="child 4", ParentId=4} }; List mi = allMenu .Where(e => e.ParentId == 0) /* grab only the root parent nodes */ .Select(e => new MenuItem { Id = e.Id, Name = e.Name, ParentId = e.ParentId, Children = GetChildren(allMenu, e.Id) /* Recursively grab the children */ }).ToList(); ViewBag.menusList = mi; return View(); } ///  /// Recursively grabs the children from the list of items for the provided parentId ///  /// List of all items /// Id of parent item /// List of children of parentId private static List GetChildren(List items, int parentId) { return items .Where(x => x.ParentId == parentId) .Select(e => new MenuItem { Id = e.Id, Name = e.Name, ParentId = e.ParentId, Children = GetChildren(items, e.Id) }).ToList(); } 

    剃刀代码

     @{ var menuList = ViewBag.menusList as List; @ShowTree(menuList); } @helper ShowTree(List menusList) { if (menusList != null) { foreach (var item in menusList) { 
  • @item.Name @if (item.Children.Any()) {
      @ShowTree(item.Children)
    }
  • } } }

    我修好并以这种方式完成工作

    问题是剃刀代码的逻辑,我也评论这一行//.Where(e => e.ParentId == 0)这里我正在添加工作代码。

    工作代码示例

     @helper ShowTree(List menu, int? parentid = 0, int level = 0) { var items = menu.Where(m => m.ParentId == parentid); if (items.Any()) { if (items.First().ParentId > 0) { level++; } 
      @foreach (var item in items) {
    • @item.Name
    • @ShowTree(menu, item.Id, level); }
    } } @{ var menuList = ViewBag.menusList as List; @ShowTree(menuList); } public ActionResult Index() { List allMenu = new List { new MenuItem {Id=1,Name="Parent 1", ParentId=0}, new MenuItem {Id=2,Name="child 1", ParentId=1}, new MenuItem {Id=3,Name="child 2", ParentId=1}, new MenuItem {Id=4,Name="child 3", ParentId=1}, new MenuItem {Id=5,Name="Parent 2", ParentId=0}, new MenuItem {Id=6,Name="child 4", ParentId=4} }; List mi = allMenu //.Where(e => e.ParentId == 0) /* grab only the root parent nodes */ .Select(e => new MenuItem { Id = e.Id, Name = e.Name, ParentId = e.ParentId, //Children = allMenu.Where(x => x.ParentId == e.Id).ToList() }).ToList(); ViewBag.menusList = mi; return View(); }