mic*_*ver 1 c# linq-to-entities
一位朋友向我展示了这个Linq声明:
records.Where( r => r.Name == "Henry Clay" ).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
撇开FirstOrDefault()可以取一个lambda的事实,在所有Henry Clay记录转到FirstOrDefault()或者Where方法只返回第一个之前,是否检查所有Henry Clay记录?
换句话说,一些亨利克莱的记录永远不会传递给FirstOrDefault?
假设您在最后找到一个项目,则不会迭代整个源序列.一旦返回第一个项目,您将立即停止.
这是一个有用的比喻.想象一下,一群人坐在一张桌子旁边."迈克"坐在最左边.每当他旁边的人要求他提供物品时,他都会从堆叠中取出一张纸并交给下一个人.他将成为基础数据的"枚举器" records.
坐在他旁边的将是"弗雷德".弗雷德,当被问到一件物品时,会问迈克一件物品.如果Mike给他的项目上写着"Henry Clay",那么他会把它交给下一个人,如果没有,他会问迈克另一个项目.这将继续下去,直到弗雷德最终获得满足他的条件的项目,或迈克用完项目.他代表的是Where普查员.
弗雷德的右边将是"亚伦".当被问到一件物品时,亚伦会向弗雷德询问一件物品.当他从弗雷德那里得到一件物品时,他会将它传递给下一个人,然后下次有人要求一件物品时,他会立刻说"不,我已经完成了"而没有向弗雷德询问任何其他事情.他代表着FirstOrDefault.
当被要求从他们旁边的人那里获得物品时,每个人只有在被要求时才从他们的"来源"获得物品,处理它或做任何他们需要的物品,以便为下一个人生成物品.你可以想象,使用这个例子,一旦亚伦得到他的第一个项目,很可能会在纸叠上留下纸张.他们将留在那里,没有人处理,因为亚伦不会要求弗雷德第二项.
不,所有元素都是懒惰地执行的.当您按如下方式重写查询时,可以看到这一点:
records.Where(r =>
{
Console.WriteLine(r.Name);
return r.Name == "Henry Clay";
})
.FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
ToArray()例如,强制执行时结果会有很大差异:
records.Where(r =>
{
Console.WriteLine(r.Name);
return r.Name == "Henry Clay";
})
.ToArray()
.FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
在最后一种情况下,ToArray()将强制records集合中所有元素的迭代,否则,FirstOrDefault()将确保在where谓词第一次返回true之后迭代停止集合.