我正在围绕 3000 员工&每个员工循环一个月的所有日期。
我已从Db预加载了一个列表ShiftDetails
以提高性能。
foreach (var item in lstEmp)
{
while (fDate <= ToDate)
{
var employeeShifts = ShiftDetails
.Where(a => a.EmployeeId == item.Id && a.ShiftDate == fDate)
.Select(a => a)
.FirstOrDefault();
}
}
当我使用Profiler检查性能时,上面一行代码正在耗费大量时间。
有什么办法可以提高代码的性能吗?
我搜索过&amp;发现字典最适合解决这个问题,但它们应该有唯一的密钥,在我的情况下,我没有列表中的任何唯一列。
答案 0 :(得分:0)
从我看到的EmployeeId&amp;组合ShiftDate可能是您唯一的密钥。
尝试使用以下内容手动创建密钥:
var key = EmployeeId.ToString() + " - " + a.ShiftDate.ToString();
然后你的搜索就像这样一行:
if (myDictionary.ContainsKey(key))
{
// .. do your logic here
}
答案 1 :(得分:0)
这个解决方案怎么样:
foreach (var item in lstEmp)
{
var employeeShifts = ShiftDetails
.Where(a => a.EmployeeId == item.Id && isInDate(a.ShiftDate))
.Select(a => a)
.FirstOrDefault();
}
代码中的任何其他位置:
public bool isInDate(date start, date end, date dateFromUserProperty){
//if dateFromUserProperty is within the range (start - end date) return true,
//else return false
}
你能解释一下这个项目是什么吗?您是否尝试在项目集合和用户集合之间建立交集?
答案 2 :(得分:0)
我会将您的操作分成两个程序:
按每个EmployeeId
根据过滤后的班次,请先按ShiftDate
在while循环之外按EmployeeId
进行过滤更快,因为我们只计算此结果一次,而不是每个月中的每个日期。将结果保存为List
也会给我们带来轻微的性能提升,因为我们可以利用List.Find
(返回给定谓词的第一个匹配值,并针对List
优化) Where
/ FirstOrDefault
。
foreach (var item in lstEmp)
{
var shiftsByEmployeeId = ShiftDetails.Where(a => a.EmployeeId == item.Id).ToList();
while (fDate <= ToDate)
{
var employeeShifts = shiftsByEmployeeId.Find(a => a.ShiftDate == fDate);
}
}