我有以下方法使用LinqToSql获取节点的所有父节点,但我不知道它对性能有多大影响。
来自NodeTable:
public partial class Node
{
public List<Node> GetAllParents(IEnumerable<Node> records)
{
if (this.ParentID == 0)
{
// Reach the parent, so create the instance of the collection and brake recursive.
return new List<Node>();
}
var parent = records.First(p => p.ID == ParentID);
// create a collection from one item to concat it with the all parents.
IEnumerable<Node> lst = new Node[] { parent };
lst = lst.Concat(parent.GetAllParents(records));
return lst.ToList();
}
}
好吗!或任何提高它的想法!!
感谢。
答案 0 :(得分:4)
因此,上面的代码是向上(父)方向的父子层次结构。因此,在最坏的情况下,它将导致对数据库的n层次深度进行n次查询。我建议您通过稍微改变方法来尝试延迟执行,例如
public IEnumerable<Node> GetAllParents(IEnumerable<Node> records)
{
if (this.ParentID == 0)
{
// Reach the parent, so create the instance of the collection and brake recursive.
return new List<Node>();
}
var parent = records.Where(p => p.ID == ParentID);
var parents = parent.Concat(parent.GetAllParents(records));
return parent;
}
我不是100%确定它是否可行但是想法是利用表达式树/延迟执行,以便在单个数据库行程中触发多个查询。
另一个想法是编写一个存储的proc / view,它将返回所有父节点(在sql server中查看相同的CTE)。
编辑:使用Where
代替First
在上面的代码中查找父级,因为First肯定会立即进行评估 - (警告:仍然未经测试的代码)
答案 1 :(得分:3)
这将导致查询每个父节点。
最好接近这个也是使用CTE编写存储过程,或者如果上述不可能,请进行广度优先搜索/查询。后者需要对每个级别进行查询,但总体上会产生更少的查询。
答案 2 :(得分:0)
我不确定你能做的事情要少得多,这是 - 我的头脑 - 相同但不是递归的,因此可能更有效率 - 但问题始终是查询父母。
List<Node> parentList = new List<Node>();
Node current = this;
while (current.ParentID != 0)
{
// current = this.Parent;
current = records.First(r => r.ID == current.ParentID);
parentList.Add(current)
}
return parentList;
答案 3 :(得分:0)
这取决于您的层次结构可能有多大。如果您知道它永远不需要递归多次不是一个问题,但是将整个表加载到内存而不是向db发送多个调用可能更快。