C# LINQ实现:将子项与父项的扁平列表转换为层级列表
如何将扁平的子项-父项列表转换为层级结构?
你已经通过多表join得到了子项与父项的扁平关联列表,要转成每个子项包含对应所有父项的层级结构,用LINQ的GroupBy配合Select就能轻松实现,这是最简洁高效的方式之一。
核心实现代码(匿名类型版本)
如果只是临时使用,不需要定义额外类,可以直接用匿名类型完成转换:
var hierarchicalList = flatList // 按子项的ID和名称分组,确保相同子项的所有父项被归到一组 .GroupBy(cwp => new { cwp.ChildId, cwp.ChildName }) // 对每个分组映射成目标结构 .Select(g => new { g.Key.ChildId, g.Key.ChildName, // 从分组中提取所有父项信息 Parents = g.Select(item => new { item.ParentId, item.ParentName }).ToList() }) .ToList();
强类型版本(推荐用于项目代码)
如果你的项目需要强类型来保证类型安全和可维护性,可以先定义对应的DTO类,再进行转换:
// 定义目标层级结构的类 public class ChildWithParents { public int ChildId { get; set; } public string ChildName { get; set; } public List<ParentDto> Parents { get; set; } = new List<ParentDto>(); } public class ParentDto { public int ParentId { get; set; } public string ParentName { get; set; } } // 执行转换 var hierarchicalList = flatList .GroupBy(cwp => new { cwp.ChildId, cwp.ChildName }) .Select(g => new ChildWithParents { ChildId = g.Key.ChildId, ChildName = g.Key.ChildName, Parents = g.Select(item => new ParentDto { ParentId = item.ParentId, ParentName = item.ParentName }).ToList() }) .ToList();
补充说明
- 分组键用
{ ChildId, ChildName }是为了确保分组的唯一性(避免不同子项ID但名称相同的情况,当然如果你的业务中ChildId本身就是唯一标识,也可以只按ChildId分组,之后从分组中取第一个项的ChildName即可)。 - 如果数据量很大,你也可以考虑在数据库层面直接做分组查询,不过EF Core对多表关联后的GROUP BY支持需要注意字段的可解析性,通常先拉取扁平列表再在内存分组是更直观且不易出错的方案。
内容的提问来源于stack exchange,提问作者levi
相关产品推荐
相关产品推荐

