是否可以编译linq-to-objects的查询

时间:2010-04-16 00:32:13

标签: c# linq linq-to-objects

我在递归循环中有一个linq到对象查询,并且害怕当对象接近1000以上并且网站上有超过100个用户时 - 我的网站将会中断。所以可以编译linq到对象查询。

linq查询只会找到节点的直接子节点。

2 个答案:

答案 0 :(得分:16)

要了解为什么编译的概念对LINQ to Object查询没有意义,理解LINQ的实现方式很有用。首先,应该清楚的是,无论您使用的LINQ的变体如何,用C#编译器将用流利语法编写的LINQ查询转换为编译时的等效方法调用语法:

from person in people
where person.Age < 18
select person.Name
// will be converted to:
people.Where(person => person.Age < 18).Select(person => person.Name)

从现在开始,LINQ查询基本上是一组带有一些参数的方法调用,通常会将IEnumerable<T>对象转换为另一个IEnumerable<T>对象。延迟执行与编译不同,只需从原始IEnumerable<T>中取任何对象直到您遍历输出IEnumerable<T>即可实现。基本上,延迟执行的方法在符号上操作它们的参数而不触及原始集合,构建一个可以根据需要查询内容的生成器。

考虑到这一点,请查看上面表达式中的lambda表达式person => person.Age < 18。它需要Person个对象并返回bool。 Lambda表达式是无类型的;它们可以被视为表达式树或匿名方法,具体取决于它们的类型推断的上下文。在这种情况下,从Where扩展方法的参数类型推断出类型。这就是LINQ to SQL和LINQ to Object的区别。在LINQ to Objects中,Where方法只需Func<Person, bool>而不是Expression<Func<Person, bool>>。这实际上意味着在LINQ to Objects中,C#编译器将lambda表达式编译为匿名方法,并在编译时生成IL,并将委托传递给该方法Where

在其他LINQ版本中,例如LINQ to SQL,lambda 编译为IL。相反,编译器从lambda表达式中构建表达式树对象,并将表达式树传递给LINQ方法。 LINQ方法使用这些表达式树来构建用于查询内容的模型。在运行查询时,构建为使用表达式树表示查询的对象模型将转换为另一种东西(取决于所使用的LINQ变体),如LINQ to SQL中的SQL语句,以便在数据库上执行。这个转换过程在运行时完成,我们称之为 LINQ查询的编译

总结一下,问题是编译到什么? LINQ to Object在运行时不需要编译的原因是它首先不是表达式树格式;它已经是IL了。

与普通循环相比,您几乎不需要担心LINQ to Objects的性能。

答案 1 :(得分:0)

与所有优化一样,当你到达那里时要担心它。如果您有超过100个用户同时连接,那么您的瓶颈将会在某个地方完全不同。