在C#中将层级结构数据库条目映射为对象的技术咨询
在C#中将层级数据库表映射为对象的实现方案
这个场景我之前处理过不少,这种自引用的层级结构表转对象其实是很常见的需求,我给你梳理一套清晰的步骤和代码示例:
步骤1:定义层级对象模型
首先我们需要一个能承载层级关系的类,每个节点既要包含自身的数据库字段属性,还要有子节点的集合:
public class HierarchyNode { public int Id { get; set; } public int PId { get; set; } public string Attribute { get; set; } public int? ParentId { get; set; } // 根节点无父ID,用可空类型适配 public int Sequence { get; set; } public List<HierarchyNode> Children { get; set; } = new List<HierarchyNode>(); // 初始化空集合避免空引用 }
步骤2:从数据库获取数据并构建层级
假设你已经通过EF Core或ADO.NET拿到了目标P_ID对应的所有数据(比如筛选PId == 1的记录),接下来用字典来高效构建层级:
// 示例:从EF Core获取指定P_ID的所有数据 var targetPId = 1; var allNodes = _dbContext.HierarchyEntries .Where(x => x.PId == targetPId) .ToList(); // 1. 把所有节点存入字典,用ID作为键,方便快速查找父节点 var nodeDictionary = allNodes.ToDictionary( node => node.Id, node => new HierarchyNode { Id = node.Id, PId = node.PId, Attribute = node.Attribute, ParentId = node.ParentId, Sequence = node.Sequence }); // 2. 遍历节点,将子节点挂载到对应父节点下 List<HierarchyNode> rootNodes = new List<HierarchyNode>(); foreach (var dbNode in allNodes) { var currentNode = nodeDictionary[dbNode.Id]; if (dbNode.ParentId == null) // 识别根节点(无父ID的条目) { rootNodes.Add(currentNode); } else { // 找到父节点并添加当前节点到子集合 if (nodeDictionary.TryGetValue(dbNode.ParentId.Value, out var parentNode)) { parentNode.Children.Add(currentNode); } } } // 3. 按SEQUENCE字段对子节点排序,保证层级顺序和数据库一致 foreach (var node in nodeDictionary.Values) { node.Children = node.Children.OrderBy(child => child.Sequence).ToList(); } // 最终rootNodes就是该P_ID下的所有顶层节点,每个节点都带有完整的子层级结构
补充细节说明
- 如果你的数据库里根节点的
PARENT_ID不是null而是其他标识(比如0),只需要把根节点判断条件改成dbNode.ParentId == 0即可。 - 要是用ADO.NET的
DataTable,只需要先把DataTable的行转换成HierarchyNode列表,后续构建逻辑完全一致。 - 这个方案的时间复杂度是O(n),字典查找是O(1),遍历两次列表即可完成构建,数据量较大时也能保证效率。
内容的提问来源于stack exchange,提问作者Abdul
相关产品推荐
相关产品推荐

