C#中验证List数组内等值JSON对象、处理重复Ordination值的问题
审批层级Ordination重复值自动修正实现方案
实现思路
- 先收集当前业务规则下所有已被占用的Ordination值,包含数据库已存储的存量数据、本次请求中需要更新的已有层级的排序值
- 对每个新增的审批层级,从传入的原始Ordination值开始递增查找,第一个未被占用的值即为可用排序值
- 每分配一个可用值就同步更新到已占用集合中,避免多个新增项重复分配同一个值
修正后代码
// 1. 收集所有已占用的Ordination值 // 若运行环境为.NET Framework 3.0无HashSet,可替换为List<int>,方法调用逻辑保持不变 HashSet<int> usedOrdinations = new HashSet<int>(); // 加入数据库中当前规则已有的审批层级排序值 var existedLevels = BusinessRuleApprovalLevel.Where(l => l.BusinessRuleId == ruleId).ToList(); foreach(var existed in existedLevels) { usedOrdinations.Add(existed.Ordination); } // 加入本次传入的非新增(有Id)层级的排序值 foreach(var level in levelsArray.Where(l => l["Id"] != null)) { if(level["Ordination"] != null && int.TryParse(level["Ordination"].ToString(), out int ord)) { usedOrdinations.Add(ord); } } // 2. 批量处理新增的审批层级 var newLevels = levelsArray.Where(l => l["Id"] == null).ToList(); foreach (JObject newLevelObject in newLevels) { BusinessRuleApprovalLevel newLevel = PloomesUtils.JsonToObject<BusinessRuleApprovalLevel>(newLevelObject); int targetOrd = newLevel.Ordination; // 查找第一个可用排序值,重复则自动+1 while(usedOrdinations.Contains(targetOrd)) { targetOrd++; } newLevel.Ordination = targetOrd; usedOrdinations.Add(targetOrd); newLevel.BusinessRuleId = ruleId; BusinessRuleApprovalLevel.Add(newLevel); // 若追求性能可把SaveChanges提到循环外,所有新增项处理完统一提交 SaveChanges(); // 处理关联用户 if (newLevelObject.Property("Users") != null && newLevelObject["Users"].Type != JTokenType.Null) { UpdateApprovalLevelUsers(newLevel.Id, (JArray)newLevelObject["Users"]); } }
可选优化
如果业务要求Ordination必须连续、可复用删除后产生的空位,可替换查找可用值的逻辑:
// 查找最小可用排序值,支持复用空缺 private int GetAvailableOrdination(HashSet<int> used) { int i = 1; while(used.Contains(i)) { i++; } return i; }
调用时直接用int targetOrd = GetAvailableOrdination(usedOrdinations);替换原有的递增查找逻辑即可。
内容的提问来源于stack exchange,提问作者Dã Primo
相关产品推荐
相关产品推荐

