(ID / ParentID)列表到分层列表

MyClass包含ID ParentIDList as Children

我有这样的MyClass列表

 ID ParentID 1 0 2 7 3 1 4 5 5 1 6 2 7 1 8 6 9 0 10 9 

输出(分层列表)为List

 1 __ 3 |__ 5__ 4 |__ 7__ 2__ 6__ 8 |__ 11 9 __10 

在linq中实现这一目标的最简单方法是什么?
PS: ParentID未排序

编辑:
我的尝试:

 class MyClass { public int ID; public int ParentID; public List Children = new List(); public MyClass(int id, int parent_id) { ID = id; ParentID = parent_id; } } 

初始化样本数据并尝试访问分层数据

  List items = new List() { new MyClass(1, 0), new MyClass(2, 7), new MyClass(3, 1), new MyClass(4, 5), new MyClass(5, 1), new MyClass(6, 2), new MyClass(7,1), new MyClass(8, 6), new MyClass(9, 0), new MyClass(10, 9), new MyClass(11, 7), }; Dictionary dic = items.ToDictionary(ee => ee.ID); foreach (var c in items) if (dic.ContainsKey(c.ParentID)) dic[c.ParentID].Children.Add(c); 

正如你所看到的,很多我不想要的东西仍然在字典中

对于分层数据,您需要递归 – foreach循环是不够的。

 Action SetChildren = null; SetChildren = parent => { parent.Children = items .Where(childItem => childItem.ParentID == parent.ID) .ToList(); //Recursively call the SetChildren method for each child. parent.Children .ForEach(SetChildren); }; //Initialize the hierarchical list to root level items List hierarchicalItems = items .Where(rootItem => rootItem.ParentID == 0) .ToList(); //Call the SetChildren method to set the children on each root level item. hierarchicalItems.ForEach(SetChildren); 

items与您使用的列表相同。 注意如何在自身内调用SetChildren方法。 这就是构建层次结构的原因。

如果在过滤之前构建父子关系,则此处不需要递归。 由于列表的成员保持相同的对象,只要您将列表的每个成员与其直接子项相关联,就会构建所有必需的关系。

这可以分为两行:

 items.ForEach(item => item.Children = items.Where(child => child.ParentID == item.ID) .ToList()); List topItems = items.Where(item => item.ParentID == 0).ToList(); 

我已经需要这样的function并且比较两种方法并找到方法2nd比第一快:),现在我的数据库卡或记录有限但第一种方法需要4倍的时间来完成。

对于那些有时间意识的人来说,这可能会有所帮助。

1方法


  public JsonResult CardData() { var watch = System.Diagnostics.Stopwatch.StartNew(); OrgChartWithApiContext db = new OrgChartWithApiContext(); var items = db.Cards.ToList(); Action SetChildren = null; SetChildren = parent => { parent.Children = items .Where(childItem => childItem.ParentId == parent.id) .ToList(); //Recursively call the SetChildren method for each child. parent.Children .ForEach(SetChildren); }; //Initialize the hierarchical list to root level items List hierarchicalItems = items .Where(rootItem => !rootItem.ParentId.HasValue) .ToList(); //Call the SetChildren method to set the children on each root level item. hierarchicalItems.ForEach(SetChildren); watch.Stop(); var timetaken = watch.ElapsedMilliseconds; return new JsonResult() { Data = hierarchicalItems, ContentType = "Json", JsonRequestBehavior = JsonRequestBehavior.AllowGet }; } 

方法2


  public JsonResult Card2Data() { var watch = System.Diagnostics.Stopwatch.StartNew(); OrgChartWithApiContext db = new OrgChartWithApiContext(); var items = db.Cards.ToList(); List topItems = items.Where(item => !item.ParentId.HasValue).ToList(); topItems.ForEach(item => item.Children = items.Where(child => child.ParentId == item.id).ToList()); watch.Stop(); var timetaken = watch.ElapsedMilliseconds; return new JsonResult() { Data = topItems, ContentType = "Json", JsonRequestBehavior = JsonRequestBehavior.AllowGet }; }