如何通过了解LINQ中的子parentID来构建根元素的路径?

时间:2018-11-01 02:40:01

标签: c# linq

我有List< MyClass >喜欢

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

我需要获得完整的root路径,如

0 __ 1__ 7__ 2__ 6__ 8

如果我们知道8 6

我的意思是我需要从父元素转到根元素并构建层次结构。

(到目前为止,我已经尝试过此LINQ to SQL - Grouping categories by parentId。)

在linq中最简单的方法是什么?

1 个答案:

答案 0 :(得分:3)

尽管您可以编写扩展方法来执行搜索并返回一个表示返回根目录的路由的IEnumerable<MyClass>,但此问题不太适合LINQ。鉴于无限循环和路由可能无法完成的可能性,最好在整个图形中跟踪进度,以确保特定的Id不会被多次访问。

public static class MyClassEx
{
    public static IEnumerable<MyClass> FindSourcePath(
        this MyClass startItem, 
        IList<MyClass> items)
    { 
        return startItem.FindSourcePath(items.ToDictionary(x => x.Id));
    }
    public static IEnumerable<MyClass> FindSourcePath(
        this MyClass startItem, 
        IDictionary<int, MyClass> itemDic)
    {
        var curr = startItem;
        var visited = new HashSet<int>();
        while (visited.Add(curr.Id))
        {
            yield return curr;
            if (curr.ParentId == 0)
            {
                yield break;
            }
            if (!itemDic.TryGetValue(curr.ParentId, out curr))
            {
                throw new Exception("invalid parent ref");
            }
        }
        throw new Exception("loop detected");
    }
}

并使用它:

List<MyClass> allItems = //...
var someItem = allItems[7];
IEnumerable<MyClass> hopsToRoot = someItem.FindSourcePath(allItems);

产生(在您的示例中)序列

-------------
| MyClass   |
-------------
Id | ParentId
=============
8  | 6 
6  | 2 
2  | 7 
7  | 1 
1  | 0