我有一个自引用表,其中包含ID、ParentID(可为空)。
因此,该表包含许多节点,每个节点可以是层次结构中的根(父项为null),或者是层次结构的任何级别(父项在表中的其他位置存在)。
给定任意起始节点,是否有一种优雅的linq查询,可以返回从该节点开始的层次结构中的所有子节点?
谢谢。
我有一个自引用表,其中包含ID、ParentID(可为空)。
因此,该表包含许多节点,每个节点可以是层次结构中的根(父项为null),或者是层次结构的任何级别(父项在表中的其他位置存在)。
给定任意起始节点,是否有一种优雅的linq查询,可以返回从该节点开始的层次结构中的所有子节点?
谢谢。
from item in table
where item.ID == parentID;
select item
我刚刚写了一个快速的例子:
class MyTable
{
public int Id { get; set; }
public int? ParentId { get; set; }
public MyTable(int id, int? parentId) { this.Id = id; this.ParentId = parentId; }
}
List<MyTable> allTables = new List<MyTable> {
new MyTable(0, null),
new MyTable(1, 0),
new MyTable(2, 1)
};
Func<int, IEnumerable<MyTable>> f = null;
f = (id) =>
{
IEnumerable<MyTable> table = allTables.Where(t => t.Id == id);
if (allTables
.Where(t => t.ParentId.HasValue && t.ParentId.Value == table
.First().Id).Count() != 0)
return table
.Union(f(
allTables.Where(t => t.ParentId.HasValue && t.ParentId.Value == table
.First().Id).First().Id));
else return table;
};
但我相信可以使用SQL和Union ALL实现。
基本上,我会按照你提供的SO链接中讨论的方式进行。
public IQueryable GetCategories(Category parent)
{
var cats = (parent.Categories);
foreach (Category c in cats )
{
cats = cats .Concat(GetCategories(c));
}
return a;
}
公用表达式(CTEs)可能是最好的解决方案,但我现在想把所有东西都保持在同一层级。