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

C# ASP.NET Web API 实现员工经理层级树形JSON输出咨询

实现员工层级树形JSON输出方案

1 调整实体类定义

首先给EmployeeHierarchy实体类新增下级员工集合属性,用于嵌套存储子节点:

public class EmployeeHierarchy
{
    public int EmployeeId { get; set; }
    public string EmployeeName { get; set; }
    public int? ManagerId { get; set; }
    public string Position { get; set; }
    // 新增下级员工集合,初始化避免空引用异常
    public List<EmployeeHierarchy> Subordinates { get; set; } = new List<EmployeeHierarchy>();
}

2 扁平数据转树形结构核心逻辑

调用存储过程拿到全部扁平化层级数据后,通过字典快速映射构建嵌套结构,无需递归,性能更高:

// 调用存储过程获取全部层级的扁平员工数据
List<EmployeeHierarchy> flatEmployeeList = dbContext.Database
    .SqlQuery<EmployeeHierarchy>("EXEC GetEmployeeHierarchy")
    .ToList();

// 构建员工ID映射字典,加快查找速度
var employeeDict = flatEmployeeList.ToDictionary(e => e.EmployeeId);

// 存储最终的根节点(最高级无上级的管理人员)
List<EmployeeHierarchy> treeRoot = new List<EmployeeHierarchy>();

foreach (var emp in flatEmployeeList)
{
    // 有上级且上级存在,就把当前员工加入上级的下级集合
    if (emp.ManagerId.HasValue && employeeDict.TryGetValue(emp.ManagerId.Value, out var manager))
    {
        manager.Subordinates.Add(emp);
    }
    // 无上级即为根节点
    else
    {
        treeRoot.Add(emp);
    }
}

3 完整API接口示例

public class EmployeeController : ApiController
{
    [HttpGet]
    [Route("api/employee/hierarchy")]
    public IHttpActionResult GetHierarchyTree()
    {
        try
        {
            using (var dbContext = new YourDbContextName())
            {
                // 1. 取扁平数据
                List<EmployeeHierarchy> flatEmployeeList = dbContext.Database
                    .SqlQuery<EmployeeHierarchy>("EXEC GetEmployeeHierarchy")
                    .ToList();

                // 2. 构建字典
                var employeeDict = flatEmployeeList.ToDictionary(e => e.EmployeeId);

                // 3. 组装树形结构
                List<EmployeeHierarchy> treeRoot = new List<EmployeeHierarchy>();
                foreach (var emp in flatEmployeeList)
                {
                    if (emp.ManagerId.HasValue && employeeDict.ContainsKey(emp.ManagerId.Value))
                    {
                        employeeDict[emp.ManagerId.Value].Subordinates.Add(emp);
                    }
                    else
                    {
                        treeRoot.Add(emp);
                    }
                }

                return Ok(treeRoot);
            }
        }
        catch (Exception ex)
        {
            return InternalServerError(ex);
        }
    }
}

4 解决JSON循环引用报错问题

因为子节点逻辑上属于父节点,直接序列化会触发循环引用错误,需要在App_Start/WebApiConfig.cs的Register方法中添加序列化配置:

// 使用Newtonsoft.Json的配置
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = 
    Newtonsoft.Json.ReferenceLoopHandling.Ignore;

// 如果是ASP.NET Core使用System.Text.Json的配置
builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.IgnoreCycles;
    });

注意事项

  • 存储过程需要返回全量员工层级数据,不能过滤或分页,否则会丢失节点无法构建完整树
  • 如果员工数据量超过1000条,建议缓存构建完成的树结构,避免每次请求重复计算

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 23:36:03