使用LINQ渲染层次结构?

Byu*_*eng 5 linq select entity-framework hierarchy

假设我们有一堂课

Category
{
   ID,
   Name,
   ParentID
}
Run Code Online (Sandbox Code Playgroud)

和一份清单

1, 'Item 1', 0
2, 'Item 2', 0
3, 'Item 3', 0
4, 'Item 1.1', 1
5, 'Item 3.1', 3
6, 'Item 1.1.1', 4
7, 'Item 2.1', 2
Run Code Online (Sandbox Code Playgroud)

我们可以使用LINQ渲染树,如:

Item 1
 Item 1.1
  Item 1.1.1
Item 2
 Item 2.1
Item 3
 Item 3.1
Run Code Online (Sandbox Code Playgroud)

任何帮助表示赞赏!

Eni*_*ity 5

这是"LINQ-only"版本:

Func<int, int, string[]> build = null;
build = (p, n) =>
{
    return (from x in categories
            where x.ParentID == p
            from y in new[]
            {
                "".PadLeft(n)+ x.Name
            }.Union(build(x.ID, n + 1))
            select y).ToArray();
};
var lines = build(0, 0);
Run Code Online (Sandbox Code Playgroud)

是的,它是递归的LINQ.


Per NVA的请求,这是使所有"孤儿"记录成为根记录的方法:

Func<IEnumerable<int>, int, string[]> build = null;
build = (ps, n) =>
{
    return (from x in categories
            where ps.Contains(x.ParentID)
            from y in new[]
    {
        "".PadLeft(n)+ x.Name
    }.Union(build(new [] { x.ID }, n + 1))
            select y).ToArray();
};

var roots = (from c in categories
             join p in categories on c.ParentID equals p.ID into gps
             where !gps.Any()
             orderby c.ParentID
             select c.ParentID).Distinct();

var lines = build(roots, 0);
Run Code Online (Sandbox Code Playgroud)