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

ASP.NET Core Web API项目多级差异化编号(1、1.a等)实现步骤问询

ASP.NET Core Web API 多级差异化编号实现方案

1. 调整实体模型结构

给检查清单、子检查清单、策略、合规项统一抽象为节点实体(或各实体共享核心字段),新增关键字段以支撑编号生成逻辑:

  • Id:节点唯一标识
  • ParentId:父节点ID(一级检查清单的ParentId为null)
  • NodeType:枚举类型,区分节点类型(Checklist/SubChecklist/Policy/ComplianceItem)
  • Number:存储生成的差异化编号(如1、1.a、1.1)
  • Name:节点名称(如"安全基线检查清单")

枚举定义示例:

public enum NodeType
{
    Checklist,
    SubChecklist,
    Policy,
    ComplianceItem
}

EF Core实体类示例:

public class ChecklistNode
{
    public int Id { get; set; }
    public int? ParentId { get; set; }
    public NodeType NodeType { get; set; }
    public string Number { get; set; } = string.Empty;
    public string Name { get; set; } = string.Empty;

    // 导航属性
    public ChecklistNode? Parent { get; set; }
    public ICollection<ChecklistNode> Children { get; set; } = new List<ChecklistNode>();
}

2. 实现编号生成核心逻辑

编写编号生成工具类,根据父节点编号和当前节点类型,生成对应格式的编号:

  • 一级检查清单:取数据库中已存在的Checklist数量+1,生成"1"、"2"这类纯数字编号
  • 子检查清单:基于父检查清单编号,按字母序列(a、b、c...)拼接,生成"1.a"、"1.b"
  • 策略:基于父检查清单编号,按数字序列(1、2、3...)拼接,生成"1.1"、"1.2"
  • 合规项:基于父策略编号,按数字序列拼接,生成"1.1.1"、"1.1.2"

工具类代码示例:

public class ChecklistNumberGenerator
{
    private readonly AppDbContext _dbContext;

    public ChecklistNumberGenerator(AppDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public async Task<string> GenerateNumberAsync(int? parentId, NodeType nodeType)
    {
        if (parentId == null)
        {
            // 生成一级检查清单编号
            var count = await _dbContext.ChecklistNodes
                .Where(n => n.NodeType == NodeType.Checklist)
                .CountAsync();
            return (count + 1).ToString();
        }

        var parentNode = await _dbContext.ChecklistNodes.FindAsync(parentId);
        if (parentNode == null)
            throw new ArgumentException("父节点不存在");

        switch (nodeType)
        {
            case NodeType.SubChecklist:
                var subCount = await _dbContext.ChecklistNodes
                    .Where(n => n.ParentId == parentId && n.NodeType == NodeType.SubChecklist)
                    .CountAsync();
                // 数字转字母:1→a,2→b...
                char suffix = (char)('a' + subCount);
                return $"{parentNode.Number}.{suffix}";
            case NodeType.Policy:
                var policyCount = await _dbContext.ChecklistNodes
                    .Where(n => n.ParentId == parentId && n.NodeType == NodeType.Policy)
                    .CountAsync();
                return $"{parentNode.Number}.{policyCount + 1}";
            case NodeType.ComplianceItem:
                var complianceCount = await _dbContext.ChecklistNodes
                    .Where(n => n.ParentId == parentId && n.NodeType == NodeType.ComplianceItem)
                    .CountAsync();
                return $"{parentNode.Number}.{complianceCount + 1}";
            default:
                throw new ArgumentException("不支持的节点类型");
        }
    }
}

3. 在API接口中集成编号生成

在添加节点的API接口中,调用编号生成工具生成编号后,再将节点数据保存到数据库。

API控制器代码示例:

[ApiController]
[Route("api/checklist")]
public class ChecklistController : ControllerBase
{
    private readonly AppDbContext _dbContext;
    private readonly ChecklistNumberGenerator _numberGenerator;

    public ChecklistController(AppDbContext dbContext, ChecklistNumberGenerator numberGenerator)
    {
        _dbContext = dbContext;
        _numberGenerator = numberGenerator;
    }

    [HttpPost]
    public async Task<IActionResult> AddNode([FromBody] AddNodeRequest request)
    {
        var nodeNumber = await _numberGenerator.GenerateNumberAsync(request.ParentId, request.NodeType);

        var newNode = new ChecklistNode
        {
            ParentId = request.ParentId,
            NodeType = request.NodeType,
            Number = nodeNumber,
            Name = request.Name
        };

        _dbContext.ChecklistNodes.Add(newNode);
        await _dbContext.SaveChangesAsync();

        return Ok(newNode);
    }
}

// 请求DTO
public class AddNodeRequest
{
    public int? ParentId { get; set; }
    public NodeType NodeType { get; set; }
    public string Name { get; set; } = string.Empty;
}

4. 查询与排序优化

查询节点时直接按Number字段排序,编号格式自带层级逻辑,可保证展示顺序符合预期(如"1" < "1.a" < "1.1" < "1.1.1" < "2")。

查询接口示例:

[HttpGet]
public async Task<IActionResult> GetAllNodes()
{
    var nodes = await _dbContext.ChecklistNodes
        .OrderBy(n => n.Number)
        .ToListAsync();
    return Ok(nodes);
}

5. 边界场景处理

  • 父节点不存在:在编号生成方法中检测并抛出明确异常
  • 子检查清单数量超26个:扩展字母序列为"aa"、"ab"格式,修改字母转换逻辑
  • 节点类型不匹配:在接口中增加校验,禁止给SubChecklist添加Policy子节点等非法操作

内容的提问来源于stack exchange,提问作者332-08 Pranav Bodakhe

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:23:10