C#中使用Random分配员工排班避免重复的问题求助
解决方案
问题根源
原代码的核心问题在于:
- 每次循环重复查询未分配班次,效率低下且可能导致重复操作同一班次;
- 随机索引的范围错误(基于员工数量而非未分配班次数量),存在索引越界风险;
- 未构建员工唯一分配的逻辑(若班次数量多于员工数量,调整循环逻辑后会出现员工重复排班的情况)。
修正后的代码
Random rnd = new Random(); PopulateDate(DateTime.Parse(txtFromDate.Text), DateTime.Parse(txtToDate.Text)); // 筛选符合条件的员工并随机打乱顺序,确保分配随机性 var EmpList = db.EmployeeTBs.Where(x => x.EmpType == "1" && x.Empstatus == "ok") .OrderBy(_ => rnd.Next()) .ToList(); // 获取所有未分配员工的班次 var unassignedShifts = db.ShiftTBs.Where(lor => lor.EmpName == null).ToList(); // 取员工和班次的最小数量,避免索引越界,同时保证每个员工仅分配一次 int assignableCount = Math.Min(EmpList.Count, unassignedShifts.Count); for (int i = 0; i < assignableCount; i++) { var targetShift = unassignedShifts[i]; var currentEmp = EmpList[i]; targetShift.EmpID = currentEmp.EmpID; targetShift.EmpName = currentEmp.EmpName; targetShift.EmpDepartment = currentEmp.DepartmentName; targetShift.EmpType = currentEmp.EmpType; } db.SubmitChanges();
关键优化点
- 随机打乱员工列表:通过
OrderBy(_ => rnd.Next())实现员工顺序随机,替代原代码中每次随机选班次的逻辑,既保证随机性又避免重复分配员工; - 一次性获取未分配班次:仅查询一次未分配班次列表,提升效率且避免重复操作同一班次;
- 边界处理:用
Math.Min限制分配次数,确保不会出现员工或班次索引越界的情况,同时严格保证每个员工仅被分配一次。
内容的提问来源于stack exchange,提问作者Mohammed D. Q
相关产品推荐
相关产品推荐

