Linq通过层次结构进行递归

时间:2013-04-23 07:27:50

标签: c# linq linq-to-entities

我有一个层次结构的数据结构如下。

表1

id | Groupname | parentId

表2

id | nodeName | parentId

表1 parentId引用table1 Id,table2 parentId也引用表1 id。

从表1中的任何ID开始,我需要打印出所有节点,然后遍历所有子组的子节点。

到目前为止我有这个

int id = 1; // replace with argument

repository.Nodes.Where(n => n.ParentId == Id).ToList().ForEach(d =>
{
  result.NodeList.Add(GetNodeDetails(n.Id));
});

任何人都可以帮助我以良好的效率linq方式循环吗?

1 个答案:

答案 0 :(得分:5)

如果我理解正确你想要展平层次结构,即最终结果应该是一个包含所有层次结构级别所有子级的平面列表。

实现这一目标的最简单方法是通过递归:

private IEnumerable<Node> GetSelfAndChildren(Node node)
{
    yield return GetNodeDetails(n.Id);
    foreach(var c in n.Children.SelectMany(GetSelfAndChildren)
        yield return c;
};


var result = repository.Nodes.Where(n => n.ParentId == Id)
                       .AsEnumerable()
                       .SelectMany(GetSelfAndChildren)
                       .ToList();

这使用递归方法获得一个平面的子列表。

这种方法有可能出现N + 1问题。根据配置,Children的每次访问都将导致数据库的往返 如果N + 1问题正在发生并导致 - 问题 - 另一种方法是首先从数据库中获取所有节点,然后执行Breadth-first search