加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

在C#中模拟CTE递归

发布时间:2020-12-15 17:47:42 所属栏目:百科 来源:网络整理
导读:假设有以下CTE返回我拥有的一些树数据(邻接模型)的级别(从 Hierarchical data in Linq – options and performance开始): WITH hierarchy_cte(id,parent_id,data,lvl) AS( SELECT id,0 AS lvl FROM dbo.hierarchical_table WHERE (parent_id IS NULL) UNION
假设有以下CTE返回我拥有的一些树数据(邻接模型)的级别(从 Hierarchical data in Linq – options and performance开始):
WITH hierarchy_cte(id,parent_id,data,lvl) AS
(
    SELECT id,0 AS lvl
    FROM dbo.hierarchical_table
    WHERE (parent_id IS NULL)

    UNION ALL

    SELECT t1.id,t1.parent_id,t1.data,h.lvl + 1 AS lvl
    FROM dbo.hierarchical_table AS t1 
    INNER JOIN hierarchy_cte AS h ON t1.parent_id = h.id
)
SELECT id,lvl
FROM hierarchy_cte AS result

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

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

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

解决方法

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

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

这是一种方法:

class TreeNode
{
    public int Id;
    public int? ParentId;
}

static void Main(string[] args)
{
    var list = new List<TreeNode>{
        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 },};

    foreach (var item in Level(list,null,0))
    {
        Console.WriteLine("Id={0},Level={1}",item.Key,item.Value);
    }
}

private static IEnumerable<KeyValuePair<int,int>> Level(List<TreeNode> list,int? parentId,int lvl)
{
    return list
        .Where(x => x.ParentId == parentId)
        .SelectMany(x => 
            new[] { new KeyValuePair<int,int>(x.Id,lvl) }.Concat(Level(list,x.Id,lvl + 1))
        );
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读