Acumatica自动编号LastNumberUsed修改后重复生成编号问题咨询
Acumatica自动编号重复键冲突处理方案
问题根因
场景核心底层逻辑是:Acumatica中DAC字段设置
IsKey=true仅代表框架逻辑层的键标识,用于页面导航、数据关联映射等场景,不会自动为该字段创建数据库级唯一约束。自动编号序列仅基于配置页的LastNumberUsed字段递增生成新编号,不会主动校验现有业务数据的编号占用情况,因此手动修改LastNumberUsed为更小值后,就会生成已被占用的编号。
解决方案
- 添加数据库层面唯一约束
针对CD字段所在的业务表,在Acumatica自定义项目中添加CD字段的唯一索引,无需直接修改原生数据库结构,从存储层彻底阻止重复CD值写入,不管是自动编号生成还是代码写入数据,只要CD重复就会触发报错,从根源避免脏数据。 - 新增自动编号分配前校验逻辑
在CD字段的FieldDefaulting事件中加入重复校验,每次分配编号后先查询业务表是否已存在相同CD值的记录,若存在则自动获取下一个编号,直到拿到未被占用的编号再完成赋值,参考代码如下:protected void _(Events.FieldDefaulting<YourDocumentDac.documentCD> e) { // 获取系统分配的自动编号 string assignedCd = AutoNumberAttribute.GetNewNumber<YourDocumentDac.documentCD>(e.Cache, e.Row); // 校验编号是否已存在 bool cdExist = SelectFrom<YourDocumentDac> .Where<YourDocumentDac.documentCD.IsEqual<@P.AsString>> .View.Select(e.Cache.Graph, assignedCd).Any(); if (cdExist) { // 递归获取下一个可用编号 e.NewValue = AutoNumberAttribute.GetNextNumber<YourDocumentDac.documentCD>(e.Cache, e.Row, DateTime.Now); return; } e.NewValue = assignedCd; } - 限制自动编号配置的修改操作
把自动编号序列配置页面的编辑权限仅分配给极少数高级管理员,同时在自动编号序列的LastNumberUsed字段的FieldUpdating事件中加入校验:如果新输入的LastNumberUsed小于对应业务表中现存的最大CD编号数值,直接拦截修改操作并抛出提示,从操作源头避免用户错误调整编号起始值。 - 已产生重复数据的修复方案
对已经生成的重复CD值的记录,如果业务允许修改历史编号,直接将旧重复记录的CD值修改为未被占用的序列值即可;如果业务要求CD编号不可修改,可以给重复的旧记录添加统一的后缀标识,同时将自动编号序列的LastNumberUsed调整为当前业务表中最大的CD编号对应的数值,确保后续新生成的编号不会和现有数据冲突。
内容的提问来源于stack exchange,提问作者Shaj
相关产品推荐
相关产品推荐

