我正在为Linq2Sql中的数据表准备数据
此代码突出显示为“可能多次枚举IEnumerable”(在Resharper中)
// filtered is an IEnumerable or an IQueryable
var total = filtered.Count();
var displayed = filtered
.Skip(param.iDisplayStart)
.Take(param.iDisplayLength).ToList();
我100%肯定Resharper是对的。
如何重写此内容以避免警告
为了澄清,我知道我可以在过滤结束时放置一个ToList,只对数据库执行一次查询,例如。
var filteredAndRun = filtered.ToList();
var total = filteredAndRun.Count();
var displayed = filteredAndRun
.Skip(param.iDisplayStart)
.Take(param.iDisplayLength).ToList();
但这会带来比我想通过网络传输更多的数据。
我期待着我不能吃蛋糕而且也吃它。 :(
答案 0 :(得分:2)
听起来你更关注IQueryable<T>
而不是IEnumerable<T>
的多次枚举。
但是,在你的情况下,没关系。
Count
调用应转换为简单且非常快速的SQL计数查询。它只是第二个实际带回任何记录的查询。
如果它是IEnumerable<T>
,那么数据就在内存中,无论如何它都会超快。
我会保持您的代码完全相同,只有当您发现性能问题严重时才会担心性能调整。 : - )
答案 1 :(得分:0)
您也可以执行类似
的操作count = 0;
displayed = new List();
iDisplayStop = param.iDisplayStart + param.iDisplayLength;
foreach (element in filteredAndRun) {
++count;
if ((count < param.iDisplayStart) || (count > iDisplayStop))
continue;
displayed.Add(element);
}
显然,这是伪代码,并且我可能在边缘条件下是一个接一个,但是该算法只用一次迭代就可以获得计数,并且只有最后显示的项目列表。