在C#中模拟CTE递归

前端之家收集整理的这篇文章主要介绍了在C#中模拟CTE递归前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
假设有以下CTE返回我拥有的一些树数据(邻接模型)的级别(从 Hierarchical data in Linq – options and performance开始):
  1. WITH hierarchy_cte(id,parent_id,data,lvl) AS
  2. (
  3. SELECT id,0 AS lvl
  4. FROM dbo.hierarchical_table
  5. WHERE (parent_id IS NULL)
  6.  
  7. UNION ALL
  8.  
  9. SELECT t1.id,t1.parent_id,t1.data,h.lvl + 1 AS lvl
  10. FROM dbo.hierarchical_table AS t1
  11. INNER JOIN hierarchy_cte AS h ON t1.parent_id = h.id
  12. )
  13. SELECT id,lvl
  14. FROM hierarchy_cte AS result

我想知道在C#而不是sql中执行递归是否会增加任何性能.任何人都可以告诉我如何执行CTE与递归C#函数相同的工作,假设我有一个IQueryable,其中Tree是一个表示层次表中的条目的实体;沿着以下方向的东西:

  1. public void RecurseTree(IQueryable<Tree> tree,Guid userId,Guid parentId,int level)
  2. {
  3. ...
  4. currentNode.level = x
  5. ...
  6. Recurse(tree...,level + 1)
  7. }

看到这很容易使用lambda表达式很酷

解决方法

sql Server中的递归是比较缓慢的,但它确实有效.

我不得不说T-sql有点有限,但从来没有这样做是为了做所有这些操作.我不相信有什么办法可以让这个事情发生在一个IQueryable如果你打算运行这个对你的sql Server实例,但你可以在内存中运行代码使用LINQ对对象在一个相对的紧凑的方式.

这是一种方法

  1. class TreeNode
  2. {
  3. public int Id;
  4. public int? ParentId;
  5. }
  6.  
  7. static void Main(string[] args)
  8. {
  9. var list = new List<TreeNode>{
  10. new TreeNode{ Id = 1 },new TreeNode{ Id = 4,ParentId = 1 },new TreeNode{ Id = 5,new TreeNode{ Id = 6,new TreeNode{ Id = 2 },new TreeNode{ Id = 7,ParentId= 2 },new TreeNode{ Id = 8,ParentId= 7 },new TreeNode{ Id = 3 },};
  11.  
  12. foreach (var item in Level(list,null,0))
  13. {
  14. Console.WriteLine("Id={0},Level={1}",item.Key,item.Value);
  15. }
  16. }
  17.  
  18. private static IEnumerable<KeyValuePair<int,int>> Level(List<TreeNode> list,int? parentId,int lvl)
  19. {
  20. return list
  21. .Where(x => x.ParentId == parentId)
  22. .SelectMany(x =>
  23. new[] { new KeyValuePair<int,int>(x.Id,lvl) }.Concat(Level(list,x.Id,lvl + 1))
  24. );
  25. }

猜你在找的C#相关文章