LinQ的延迟执行
表达式“from x in xEnumberbleCollection select y”构造了一个“查询语句”,可以理解为类似的SQL语句,但有了语句并不代表就有了数据结果,语句必须执行才有结果。
首先,这条LinQ语句返回了一个IEnumerator<y>对象,这个接口包含一个GetEnumerator()方法,当执行Foreach语句,这个方法就会被调用。而在GetEnumerator()方法里面,通知执行前面LinQ构造出来的“查询语句”而得出数据结果。
就比如我们构建了一个SQL语句(这时并没有数据),在调用Load()方法,发送这条语句到数据库,然后执行返回结果。而在LinQ充当Load角色(更广泛来说,应该执行数据操作)的正是GetEnumerator()方法。
总结:LinQ语法,只是构造了“查询语句”,真正执行这种语句的是IEnumerator<T>里的GetEnumerator()方法,因此,当调用GetEnumerator(),就真正执行一次LinQ获取数据,多次调用GetEnumerator(),就多次执行LinQ。这里也解释了,中途修改LinQ(即修改了“查询语句”),下次执行GetEnumerator()方法的结果就会相应地改变了。
由于每调用一次GetEnumerator(),就执行一次LinQ,在“查询语句”不变的情况下,就会出现多次重复的查询操作(结果一样),这种情况下,有必要使用ToList(),ToArray()这样的方法把结果固定下来(其实也就是调用GetEnumerator方法返回结果来装载List,Array),然后操作相应的List,Array,避免重复的查询操作。
注:调用Foreach语法,会调用GetEnumerator(),因此会真正地执行LinQ查询。

浙公网安备 33010602011771号