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

基于.NET Web Api与Dapper实现父子层级SQL表转Treeview JSON的问题

实现方案

1. 修正模型定义

你当前的模型字段设计有误,混淆了外键字段和子集合的定义,调整如下:

public class Region
{
    public int RegionId { get; set; }
    public string RegionName { get; set; }
    // 对应表的外键字段,存储父级区域ID,和表字段名保持一致方便Dapper映射
    public int? FK_RegionParentId { get; set; }
    // 子级区域集合,序列化后自动生成层级结构
    public ICollection<Region> Children { get; set; } = new List<Region>();
}

你的表结构本身是标准的自关联设计,没有问题。

2. Dapper查询与树形组装逻辑

不需要多次查询数据库,一次拉取全量数据后在内存组装即可,实现逻辑非常简单:

// 第一步:用Dapper一次性查询所有区域数据
using var connection = new SqlConnection(你的连接字符串);
var allRegions = connection.Query<Region>("SELECT * FROM Regions").ToList();

// 第二步:把所有数据存入字典,方便快速查找父级节点
var regionDict = allRegions.ToDictionary(r => r.RegionId);

// 第三步:遍历组装层级
var rootRegions = new List<Region>();
foreach (var region in allRegions)
{
    if (region.FK_RegionParentId == null)
    {
        // 无父级的节点为根节点
        rootRegions.Add(region);
    }
    else
    {
        // 找到对应父级,将当前节点加入父级的子集合
        if (regionDict.TryGetValue(region.FK_RegionParentId.Value, out var parentRegion))
        {
            parentRegion.Children.Add(region);
        }
    }
}

// 第四步:直接返回根节点集合,序列化后就是层级结构的JSON
return Ok(rootRegions);

3. 最终返回效果示例

[
    {
        "regionId": 1,
        "regionName": "Europe",
        "fk_RegionParentId": null,
        "children": [
            {
                "regionId": 4,
                "regionName": "France",
                "fk_RegionParentId": 1,
                "children": []
            }
        ]
    },
    {
        "regionId": 2,
        "regionName": "Asia",
        "fk_RegionParentId": null,
        "children": [
            {
                "regionId": 6,
                "regionName": "China",
                "fk_RegionParentId": 2,
                "children": [
                    {"regionId":8,"regionName":"Hong Kong","fk_RegionParentId":6,"children":[]},
                    {"regionId":9,"regionName":"Beijing","fk_RegionParentId":6,"children":[]},
                    {"regionId":10,"regionName":"Shanghai","fk_RegionParentId":6,"children":[]}
                ]
            },
            {
                "regionId":5,
                "regionName":"India",
                "fk_RegionParentId":2,
                "children":[]
            }
        ]
    },
    {
        "regionId":3,
        "regionName":"Africa",
        "fk_RegionParentId":null,
        "children":[
            {"regionId":7,"regionName":"Zimbabwe","fk_RegionParentId":3,"children":[]}
        ]
    }
]

补充说明

  • 你之前返回的父级ID全为null,就是因为模型字段名和表字段不匹配,Dapper无法自动映射,修正字段名即可解决
  • 这个方案性能远高于EF的递归延迟加载,只要全量数据不超过十万级都不会有性能问题
  • 如果不需要返回空的children集合,可以在JSON序列化配置里开启忽略空集合的规则即可

内容的提问来源于stack exchange,提问作者sula1337

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 21:45:03