如何为EF Core嵌套查询返回的层级子列表自动设置递增Level值
EF Core层级分类树Level字段自动赋值实现方案(CQRS架构)
实现思路
基于你现有的多层级Include查询逻辑,在CQRS的Query处理层通过递归映射的方式完成实体到响应模型的转换,递归过程中自动传递并累加层级数值,实现Level字段的自动赋值。
具体实现步骤
- 新增递归映射扩展方法
封装通用的实体到响应模型的转换逻辑,递归处理子分类时层级自动+1:
public static class CategoryMappingExtensions { /// <summary> /// 分类实体集合转层级响应模型集合 /// </summary> /// <param name="rootCategories">顶层分类实体集合</param> /// <param name="rootLevel">根节点层级起始值,默认1</param> public static List<CategoryTreeResponse> ToTreeResponse(this IEnumerable<Category> rootCategories, int rootLevel = 1) { return rootCategories.Select(c => MapToResponse(c, rootLevel)).ToList(); } private static CategoryTreeResponse MapToResponse(Category category, int currentLevel) { return new CategoryTreeResponse { Key = category.Id, // 替换为你的分类实体主键字段名 Title = category.Name, // 替换为你的分类实体名称字段名 Level = currentLevel, CommissionRate = category.CommissionRate, TermDay = category.TermDay, IsDelete = category.IsDelete, // 递归处理子分类,层级+1 Children = category.SubCategories?.Select(sub => MapToResponse(sub, currentLevel + 1)).ToList() }; } }
- CQRS QueryHandler中调用转换
在对应查询的处理器中,先调用仓储方法获取带嵌套子分类的原始实体数据,再调用上述扩展方法完成转换即可:
// 示例QueryHandler代码,根据你实际的CQRS框架(如MediatR)调整 public class GetCategoryTreeQueryHandler : IRequestHandler<GetCategoryTreeQuery, IEnumerable<CategoryTreeResponse>> { private readonly ICategoryRepository _categoryRepo; public GetCategoryTreeQueryHandler(ICategoryRepository categoryRepo) { _categoryRepo = categoryRepo; } public async Task<IEnumerable<CategoryTreeResponse>> Handle(GetCategoryTreeQuery request, CancellationToken cancellationToken) { // 查询顶层分类,过滤条件根据你实际的父级字段调整,比如ParentId为null表示根节点 var rootCategories = await _categoryRepo.GetTreeAsync(predicate: c => c.ParentId == null); // 自动生成带Level的层级响应 return rootCategories.ToTreeResponse(rootLevel: 1); } }
注意事项
- 若需要调整根节点的起始Level值,修改
ToTreeResponse方法的rootLevel参数即可,比如要根节点从0开始传0即可。 - 你现有仓储方法最多支持5级子分类的查询,若需要支持更深层级,可调整Include的层数,或改用数据库递归CTE的方式查询无限层级分类树。
- 你已在Include中过滤了软删除的子分类,映射过程中不会出现已删除的节点,无需额外处理。
内容的提问来源于stack exchange,提问作者user16695025
相关产品推荐
相关产品推荐

