我知道以不同的顺序执行操作会产生不同的性能,例如以下慢速查询之间的差异:
List<TestItem> slowResults = items.OrderBy(item => item.StringItem)
.Where(item => item.IntItem == 100)
.ToList();
还有这个更快的:
List<TestItem> fastResults = items.Where(item => item.IntItem == 100)
.OrderBy(item => item.StringItem)
.ToList();
但这不是我的问题:
对于不同的 LINQ 提供商,答案会有所不同。特别是,LINQ to Objects 和 LINQ to Entities 的情况非常不同。
在 LINQ to Objects 中,Where 运算符接受 Func 形式的筛选器。 Func 是一个委托,因此出于本次讨论的目的,您可以将其视为函数指针。在 LINQ to Objects 中,您的查询相当于:
static void Main() {
List<TestItem> results = items.Where(MyFilter).ToList();
static boolean MyFilter(TestItem item) {
return item.Item1 == 12 &&
item.Item2 != null &&
item.Item2.SubItem == 65 &&
item.Item3.Equals(anotherThingy)
}
主要需要注意的是 MyFilter 是一个普通的 C# 方法,因此适用普通的 C# 规则,包括 && 的短路行为。因此,条件将按照您编写的顺序进行评估。 LINQ to Objects 可以在不同的输入元素上调用 MyFilter,但它不能更改 MyFilter 的功能。
在 LINQ to Entities 和 LINQ to SQL 中,Where 运算符将筛选器接受为表达式>。现在,过滤器作为描述表达式的数据结构传递到Where 运算符。在这种情况下,LINQ 提供程序将查看数据结构(“表达式树”),并由 LINQ 提供程序决定如何解释它。
在 LINQ to Entities 和 LINQ to SQL 情况下,表达式树将转换为 SQL。然后由数据库服务器决定如何执行查询。绝对允许服务器对条件进行重新排序,并且它可能会进行更实质性的优化。例如,如果 SQL 表包含条件中引用的列之一的索引,则服务器可以选择使用该索引,甚至避免查看与该特定条件部分不匹配的行。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)