You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core编写GET API获取指定员工到CEO的管理层级链

解决方案

现有代码问题分析

你当前的代码仅对员工表做了一次自连接,只能获取到指定员工的直接上级,无法实现向上递归查询到CEO的完整链路;同时直接将整张员工表加载到内存,当数据量较大时会出现严重的性能问题。

推荐方案:SQL Server 递归CTE实现(性能最优)

直接在数据库层通过递归公共表达式完成层级查询,避免全表数据拉取到应用侧,适合各种数据量场景。

递归查询SQL示例

-- 入参 @TargetEmpId 为你要查询的员工ID
WITH EmpHierarchy AS
(
    -- 锚点:定位目标员工
    SELECT Id, MngId, EmployeeName, 0 AS SortSeq
    FROM Employees
    WHERE Id = @TargetEmpId

    UNION ALL

    -- 递归向上查询上级,直到无上级(CEO)
    SELECT e.Id, e.MngId, e.EmployeeName, eh.SortSeq - 1
    FROM Employees e
    INNER JOIN EmpHierarchy eh ON e.Id = eh.MngId
)
-- 拼接为连续字符串,排序后得到从直接上级到CEO的顺序
SELECT STRING_AGG(EmployeeName, '') WITHIN GROUP (ORDER BY SortSeq) AS HierarchyChain
FROM EmpHierarchy
WHERE Id != @TargetEmpId -- 排除查询员工自身

如果你的SQL Server版本低于2017不支持STRING_AGG,可以将查询结果返回到C#侧再做字符串拼接。

API侧代码调整

通过EF Core执行原生SQL获取结果即可:

[Route("empLevel/{id}")]
public IActionResult GetEmpHierarchy(int id)
{
    // 校验员工是否存在
    var empExists = entity.Employees.Any(e => e.Id == id);
    if (!empExists)
    {
        return NotFound("指定员工不存在");
    }

    // 执行递归CTE查询
    var result = entity.Employees
        .FromSqlRaw(@"WITH EmpHierarchy AS
                    (
                        SELECT Id, MngId, EmployeeName, 0 AS SortSeq
                        FROM Employees
                        WHERE Id = {0}
                        UNION ALL
                        SELECT e.Id, e.MngId, e.EmployeeName, eh.SortSeq - 1
                        FROM Employees e
                        INNER JOIN EmpHierarchy eh ON e.Id = eh.MngId
                    )
                    SELECT STRING_AGG(EmployeeName, '') WITHIN GROUP (ORDER BY SortSeq) AS HierarchyChain
                    FROM EmpHierarchy
                    WHERE Id != {0}", id)
        .AsEnumerable()
        .FirstOrDefault()?.ToString() ?? string.Empty;

    return Ok(new { EmpId = id, HierarchyChain = result });
}

备选方案:C#内存递归实现(仅适合小数据量场景)

如果员工数据量极小(低于1000条),也可以在应用侧通过递归查询实现:

[Route("empLevel/{id}")]
public IActionResult GetEmpHierarchy(int id)
{
    var allEmps = entity.Employees.ToList();
    var targetEmp = allEmps.FirstOrDefault(e => e.Id == id);
    if (targetEmp == null)
    {
        return NotFound("指定员工不存在");
    }

    var chain = new List<string>();
    var currentMngId = targetEmp.MngId;
    while (currentMngId != null)
    {
        var manager = allEmps.FirstOrDefault(e => e.Id == currentMngId.Value);
        if (manager == null) break;
        chain.Add(manager.EmployeeName);
        currentMngId = manager.MngId;
    }

    var result = string.Join("", chain);
    return Ok(new { EmpId = id, HierarchyChain = result });
}

边界情况说明

  • 如果查询的员工本身就是CEO(MngId为NULL),返回空字符串
  • 若中间出现上级ID不存在的脏数据,自动终止查询返回已找到的层级链

内容的提问来源于stack exchange,提问作者Coder-Persona

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 18:54:04