我是LINQ的新手,昨天发现你可以有多个where子句,例如:
var items = from object in objectList
where object.value1 < 100
where object.value2 > 10
select object;
Run Code Online (Sandbox Code Playgroud)
或者你可以写:
var items = from object in objectList
where object.value1 < 100
&& object.value2 > 10
select object;
Run Code Online (Sandbox Code Playgroud)
两者有什么区别?
Phi*_*ppe 19
第一个将被翻译成:
objectList.Where(o => o.value1 < 100).Where(o=> o.value2 > 10)
Run Code Online (Sandbox Code Playgroud)
而第二个将翻译成:
objectList.Where(o => o.value1 < 100 && o.value2 > 10)
Run Code Online (Sandbox Code Playgroud)
因此,在第一个中,您将有一个第一个过滤的序列再次过滤(第一个序列包含值<100的所有对象,第二个序列包含第一个序列中值> 10的所有对象),而第二个你将在同一个labda表达式中进行相同的比较.这对于Linq到对象是有效的,对于其他提供者,它取决于表达式的翻译方式.
Tam*_*red 10
明确的答案让它有点不准确.
正如@Philippe所说,第一个将被翻译成:
objectList.Where(o => o.value1 < 100).Where(o=> o.value2 > 10)
Run Code Online (Sandbox Code Playgroud)
而第二个将翻译成:
objectList.Where(o => o.value1 < 100 && o.value2 > 10)
Run Code Online (Sandbox Code Playgroud)
但 Linq对链式Where通话有一点优化.
如果您检查Linq's源代码,您将看到以下内容:
class WhereEnumerableIterator<TSource> : Iterator<TSource>
{
public override IEnumerable<TSource> Where(Func<TSource, bool> predicate)
{
return new WhereEnumerableIterator<TSource>(source,
CombinePredicates(this.predicate, predicate));
}
}
Run Code Online (Sandbox Code Playgroud)
CombinePredicates将两个谓词组合在一起是什么&&:
static Func<TSource, bool> CombinePredicates<TSource>(Func<TSource, bool> predicate1,
Func<TSource, bool> predicate2)
{
return x => predicate1(x) && predicate2(x);
}
Run Code Online (Sandbox Code Playgroud)
所以objectList.Where(X).Where(Y)相当于objectList.Where(X && Y)除了查询的创建时间(无论如何都非常短)和两个谓词的调用.
底线是它不会过滤或迭代集合两次 - 而是一个复合时间.
第一个转换为:
objectList.Where(o => o.value1 < 100)
.Where(o => o.value2 > 10);
Run Code Online (Sandbox Code Playgroud)
而后者得到你:
objectList.Where(o => o.value1 < 100 && o.value2 > 10);
Run Code Online (Sandbox Code Playgroud)
它的功能完全相同,虽然第二个会省去方法调用,但性能上的差异可以忽略不计.使用对你来说更具可读性的东西.
也就是说,如果你正在使用linq来对象.如果您正在使用提供程序,则取决于它的实现方式(如果在结果查询中未考虑谓词,则结果可能是次优的).
| 归档时间: |
|
| 查看次数: |
14075 次 |
| 最近记录: |