我有以下方法:
private static List<List<job>> SplitJobsByMonth(IEnumerable<job> inactiveJobs)
{
List<List<job>> jobsByMonth = new List<List<job>>();
DateTime cutOff = DateTime.Now.Date.AddMonths(-1).Date;
cutOff = cutOff.AddDays(-cutOff.Day + 1);
List<job> temp;
while (inactiveJobs.Count() > 0)
{
temp = inactiveJobs.Where(j => j.completeddt >= cutOff).ToList();
jobsByMonth.Add(temp);
inactiveJobs = inactiveJobs.Where(a => !temp.Contains(a));
cutOff = cutOff.AddMonths(-1);
}
return jobsByMonth;
}
它旨在按月拆分工作。 'job'是一个类,而不是一个结构。在while循环中,每次迭代都会重置传入的IEnumerable以删除已处理的作业:
inactiveJobs = inactiveJobs.Where(a => !temp.Contains(a));
通常,这会大大减少此集合的内容。但是,在下一次迭代中,行:
temp = inactiveJobs.Where(j => j.completeddt >= cutOff).ToList();
将inactiveJobs对象恢复到传递给方法时的状态 - 因此集合再次满了。 我通过稍微重构这个方法解决了这个问题,但我很好奇为什么会出现这个问题,因为我无法解释它。任何人都可以解释为什么会这样吗?
答案 0 :(得分:1)
为什么不直接使用小组?
private static List<List<job>> SplitJobsByMonth(IEnumerable<job> inactiveJobs)
{
var jobsByMonth = (from job in inactiveJobs
group job by new DateTime(job.completeddt.Year, job.completeddt.Month, 1)
into g
select g.ToList()).ToList();
return jobsByMonth;
}
答案 1 :(得分:0)
这是因为延迟执行LINQ的Where
。
当你这样做时
inactiveJobs = inactiveJobs.Where(a => !temp.Contains(a));
在您开始迭代IEnumerable
之前,实际上并未进行任何评估。如果您在ToList
之后添加Where
,则会立即进行迭代,因此interactiveJobs
的内容会减少:
inactiveJobs = inactiveJobs.Where(a => !temp.Contains(a)).ToList();
答案 2 :(得分:0)
在 LINQ 中,查询有两种不同的执行行为:立即和延迟。
查询实际上是在迭代查询变量时执行的,而不是在创建查询变量时执行的。这称为延迟执行。
您还可以强制查询立即执行,这对缓存查询结果非常有用。
为了在你的行末添加.ToList()
:
inactiveJobs = inactiveJobs.Where(a => !temp.Contains(a)).ToList();
这会立即执行创建的查询并将结果写入您的变量。
您可以详细了解this example Here。