You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C# LINQ实现分类与父分类的无限层级结构查询

实现无限层级分类结构的C# LINQ解决方案

需求说明

需要将分类表通过循环引用实现无限层级结构,目标展示结构如下:

Automotive - vehicle hire 
           - Vehicle Sales
Tyre's And Shocks - Tyres  - dunlop
                           - continental
                  - Shocks - Gabriel
                           - No Name

现有代码片段:

var category = _context.Category.Where(c.ParentCategoryId == 11).ToList();

分类表结构:

CategoryIDParentCategoryIDCategoryName
1nullAutomotive
21Vehicle Hire
31Vehicle Sales
41Spares or Accessories
51Automotive Associations
61Financial Institutions
71Health Care
81Panelbeaters
91Auto Glass
101Mags or Rims
111Tyre's And Shocks
1211Tyres
1311Shocks
1411Exhausts
1511Suspension Springs
1612Dunlop
1712Continental
1813Gabriel
1913No Name

实现方案

1. 调整分类实体类

首先在Category实体中添加子分类集合属性,用于存储当前分类的下级节点:

public class Category
{
    public int CategoryID { get; set; }
    public int? ParentCategoryID { get; set; }
    public string CategoryName { get; set; }
    // 子分类集合,初始化空列表避免空引用
    public ICollection<Category> SubCategories { get; set; } = new List<Category>();
}

2. 递归构建无限层级结构

为了减少数据库查询次数,先一次性加载所有分类数据到内存,再通过递归方法构建层级:

// 一次性加载所有分类
var allCategories = _context.Category.ToList();

// 递归构建指定父ID的分类层级
List<Category> BuildCategoryHierarchy(int? parentId)
{
    return allCategories
        .Where(c => c.ParentCategoryID == parentId)
        .Select(c => 
        {
            // 递归加载当前分类的子分类
            c.SubCategories = BuildCategoryHierarchy(c.CategoryID);
            return c;
        })
        .ToList();
}

// 构建根分类层级(ParentCategoryID为null的分类)
var fullHierarchy = BuildCategoryHierarchy(null);

// 若只需构建ParentCategoryID=11的分类层级,调用:
// var targetHierarchy = BuildCategoryHierarchy(11);

3. 格式化输出层级结构

编写递归方法按要求格式输出层级:

void PrintCategoryHierarchy(List<Category> categories, int indentLevel = 0)
{
    foreach (var category in categories)
    {
        // 根据层级生成缩进
        var indent = new string(' ', indentLevel * 9);
        if (indentLevel > 0)
        {
            indent = indent.Substring(0, indent.Length - 1) + "- ";
        }
        Console.WriteLine($"{indent}{category.CategoryName}");
        
        // 递归输出子分类
        if (category.SubCategories.Any())
        {
            PrintCategoryHierarchy(category.SubCategories, indentLevel + 1);
        }
    }
}

// 调用输出方法
PrintCategoryHierarchy(fullHierarchy);

4. 可选:用GroupJoin实现非递归构建(限固定层级)

如果确定分类层级是固定的,也可以用GroupJoin一次性关联父级和子级,但这种方式不支持无限层级:

var allCategories = _context.Category.ToList();

var fixedHierarchy = allCategories
    .Where(c => c.ParentCategoryID == null)
    .Select(c => new Category
    {
        CategoryID = c.CategoryID,
        ParentCategoryID = c.ParentCategoryID,
        CategoryName = c.CategoryName,
        SubCategories = allCategories
            .Where(sc => sc.ParentCategoryID == c.CategoryID)
            .Select(sc => new Category
            {
                CategoryID = sc.CategoryID,
                ParentCategoryID = sc.ParentCategoryID,
                CategoryName = sc.CategoryName,
                SubCategories = allCategories.Where(s => s.ParentCategoryID == sc.CategoryID).ToList()
            })
            .ToList()
    })
    .ToList();

内容的提问来源于stack exchange,提问作者Krivahn Doss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 06:30:47