EF Core如何递归加载无限层级分类父级以生成面包屑?
无限层级分类面包屑的实现方案
EF Core 支持情况
EF Core 没有内置的无限层级关联查询能力,Include 和 ThenInclude 只能指定固定深度的关联,无法动态处理无限层级的分类结构。不建议用多层 Include 或者应用层递归查询(会产生N+1查询,性能极差),推荐直接通过数据库递归查询获取完整层级路径。
推荐实现方式:递归CTE(TSQL)
通过SQL的递归公共表表达式(CTE)可以高效获取从当前节点到根节点的所有层级,再调整顺序得到面包屑所需的路径。
针对你的分类数据,获取ID=4(Sport shoes)的面包屑TSQL代码如下:
WITH CategoryHierarchy AS ( -- 锚点:选中当前分类节点 SELECT Id, Title, ParentId, 0 AS Level FROM Categories WHERE Id = 4 -- 替换为目标分类ID UNION ALL -- 递归:向上遍历父节点 SELECT c.Id, c.Title, c.ParentId, ch.Level + 1 FROM Categories c INNER JOIN CategoryHierarchy ch ON c.Id = ch.ParentId ) -- 按层级倒序,得到从根到当前节点的顺序 SELECT Title FROM CategoryHierarchy ORDER BY Level DESC;
执行后会返回:Style、Men、Shoes、Sport shoes,直接用/拼接即可得到目标面包屑字符串。
EF Core 中调用该SQL
可以通过FromSqlRaw在EF Core中执行上述CTE,获取结果后拼接面包屑:
int targetCategoryId = 4; var breadcrumbItems = await _context.Categories .FromSqlRaw(@" WITH CategoryHierarchy AS ( SELECT Id, Title, ParentId, 0 AS Level FROM Categories WHERE Id = {0} UNION ALL SELECT c.Id, c.Title, c.ParentId, ch.Level + 1 FROM Categories c INNER JOIN CategoryHierarchy ch ON c.Id = ch.ParentId ) SELECT Title FROM CategoryHierarchy ORDER BY Level DESC", targetCategoryId) .Select(c => c.Title) .ToListAsync(); string breadcrumb = string.Join(" / ", breadcrumbItems); // 结果:"Style / Men / Shoes / Sport shoes"
内容的提问来源于stack exchange,提问作者Milad Ahmadi
相关产品推荐
相关产品推荐

