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

C#递归实现BOM物料清单各层级步长10流水序号设置咨询

C# 实现BOM物料清单层级按规则生成序列编号方案

核心实现思路

  • 层级跟踪:递归函数传入currentLevel参数,每进入下一级子项递归时参数+1,返回上一级时自动恢复,无需额外维护
  • 层级计数器管理:使用Dictionary<int, int>存储每个层级的当前序列值,仅维护当前遍历路径上的层级计数,切换父项时自动重置子层级的初始值,避免不同父项的子序列互相干扰

完整代码实现

1. BOM实体定义

public class BomItem
{
    /// <summary>
    /// 物料ID
    /// </summary>
    public int Id { get; set; }
    /// <summary>
    /// 父物料ID,顶层物料默认值为0
    /// </summary>
    public int ParentId { get; set; }
    /// <summary>
    /// 物料所在层级
    /// </summary>
    public int Level { get; set; }
    /// <summary>
    /// 生成的序列值
    /// </summary>
    public int SequenceNumber { get; set; }
    /// <summary>
    /// 子物料列表
    /// </summary>
    public List<BomItem> Children { get; set; } = new List<BomItem>();
}

2. 序列生成核心逻辑

public class BomNumberGenerator
{
    /// <summary>
    /// 层级计数器,key为层级,value为当前层级已生成的最新序列值
    /// </summary>
    private readonly Dictionary<int, int> _levelCounter = new Dictionary<int, int>();
    // 序列规则配置:起始值10,步长10
    private const int StartNumber = 10;
    private const int Step = 10;

    /// <summary>
    /// 入口方法:传入顶层BOM集合生成序列
    /// </summary>
    public void GenerateSequenceNumbers(List<BomItem> rootItems)
    {
        _levelCounter.Clear();
        // 顶层物料默认层级为1
        RecursiveGenerate(rootItems, 1);
    }

    /// <summary>
    /// 递归生成序列
    /// </summary>
    private void RecursiveGenerate(List<BomItem> items, int currentLevel)
    {
        foreach (var item in items)
        {
            // 计算当前项的序列值
            if (!_levelCounter.ContainsKey(currentLevel))
            {
                _levelCounter[currentLevel] = StartNumber;
            }
            else
            {
                _levelCounter[currentLevel] += Step;
            }
            item.SequenceNumber = _levelCounter[currentLevel];
            item.Level = currentLevel;

            // 处理子项前清空所有更深层级的计数器,保证下一级序列从10重新开始
            var higherLevels = _levelCounter.Keys.Where(k => k > currentLevel).ToList();
            foreach (var level in higherLevels)
            {
                _levelCounter.Remove(level);
            }

            // 递归处理子项,层级+1
            if (item.Children.Any())
            {
                RecursiveGenerate(item.Children, currentLevel + 1);
            }
        }
    }
}

3. 调用示例

// 构造符合你示例的BOM树形结构
var root1 = new BomItem { Id = 1 };
var child2_1 = new BomItem { Id = 2 };
var child2_2 = new BomItem { Id = 5 };
var child2_3 = new BomItem { Id = 11 };
root1.Children.AddRange(new[] { child2_1, child2_2, child2_3 });

var child3_1 = new BomItem { Id = 3 };
var child3_2 = new BomItem { Id = 4 };
child2_1.Children.AddRange(new[] { child3_1, child3_2 });

var child3_3 = new BomItem { Id = 6 };
var child3_4 = new BomItem { Id = 8 };
child2_2.Children.AddRange(new[] { child3_3, child3_4 });

var child4_1 = new BomItem { Id =7 };
child3_3.Children.Add(child4_1);

var child4_2 = new BomItem { Id =9 };
var child4_3 = new BomItem { Id =10 };
child3_4.Children.AddRange(new[] { child4_2, child4_3 });

var child3_5 = new BomItem { Id =12 };
child2_3.Children.Add(child3_5);

var root2 = new BomItem { Id =13 };
var root3 = new BomItem { Id =14 };
var rootItems = new List<BomItem> { root1, root2, root3 };

// 执行序列生成
var generator = new BomNumberGenerator();
generator.GenerateSequenceNumbers(rootItems);

运行后所有BomItem的SequenceNumber和你提供的示例表格完全一致。

性能说明

该实现时间复杂度为O(n),n为BOM总项数,字典操作均为O(1)复杂度,递归深度最多15层远低于C#默认栈深度限制,几千行数据处理无性能压力。如果你的原始BOM是扁平存储(仅存ParentId无Children集合),先按ParentId分组构建树形结构再调用上述方法即可。

内容的提问来源于stack exchange,提问作者André Cooke

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 17:18:03