如何在C#中实现数据库父子结构的层级化列表展示
问题:如何将数据库中的父子结构数据生成嵌套的Category层级列表?
数据库中的父子结构数据
| id | text | parentid |
|---|---|---|
| 1 | A | NULL |
| 2 | B | NULL |
| 5 | a1 | 1 |
| 6 | b1 | 2 |
| 9 | a11 | 5 |
| 10 | a12 | 5 |
| 11 | b12 | 6 |
已定义的Category类
public class Category { public int id { get; set; } public string text{ get; set; } public int? ParentId { get; set; } public List<Category> children; }
原代码及遇到的问题
我尝试用下面的代码生成嵌套列表,但输出的JSON把所有节点都放在了同一层级,还重复显示子元素,完全不符合预期:
List<Category> cats = new List<Category>(); while (sdr.Read()) { Category c = new Category(); //从数据库填充类数据 cats.Add(c); } var child=cats.ToLookup(cat=>cat.ParentId ); foreach (var cat in cats) cat.children=child[cat.id].ToList();
我期望的JSON输出是标准的嵌套层级结构:
[{"children":[{"children":[{"children":[],"id":9,"text":"a11","ParentId":5},{"children":[],"id":10,"text":"a12","ParentId":5}],"id":5,"text":"a1","ParentId":1}],"id":1,"text":"A","ParentId":null},{"children":[{"children":[{"children":[],"id":11,"text":"b12","ParentId":6}],"id":6,"text":"b1","ParentId":2}],"id":2,"text":"B","ParentId":null}]
解决方案
问题出在你把所有节点都留在了根列表里,而且没筛选出真正的根节点(ParentId为null的节点)作为输出起点。咱们只需要在现有代码基础上做两处小修改:
- 初始化每个
Category的children列表,避免序列化时出现null; - 最终只收集
ParentId为null的根节点,而不是返回所有节点。
修改后的完整代码:
List<Category> cats = new List<Category>(); while (sdr.Read()) { Category c = new Category(); // 填充数据库数据(这里补充了具体的填充逻辑,你可以根据实际情况调整) c.id = sdr.GetInt32(0); c.text = sdr.GetString(1); c.ParentId = sdr.IsDBNull(2) ? null : sdr.GetInt32(2); c.children = new List<Category>(); // 初始化空列表,对应期望输出的[] cats.Add(c); } // 构建父ID到子节点的映射,这部分你的代码是对的 var childLookup = cats.ToLookup(cat => cat.ParentId); // 给每个节点绑定子节点 foreach (var cat in cats) { cat.children = childLookup[cat.id].ToList(); } // 关键一步:只取根节点作为最终的嵌套列表 List<Category> nestedCategories = cats.Where(cat => cat.ParentId == null).ToList();
逻辑说明
- 初始化
children:这样序列化JSON时,没有子节点的节点会显示[]而不是null,和你期望的输出格式完全匹配; - 筛选根节点:原来的
cats列表包含了所有层级的节点(根、子、孙),直接序列化会把所有节点平铺。现在只取根节点,而每个根节点已经通过children关联了它的子节点,子节点又关联了孙节点,这样就形成了完美的嵌套层级结构。
内容的提问来源于stack exchange,提问作者Zeynep
相关产品推荐
相关产品推荐

