linq中延迟执行
linq中延迟执行
linq中延迟执行LINQ执行过程的一个重要特征是延迟执行,Linq的大多数查询运算符并不是在构建的时候就立即执行,所有标准查询运算符均为延时执行,但是有的运算符不支持延时执行的机制,而是立即执行,如Count 、ToAarry、toLookup等。
一、LINQ延迟执行优点
1、LinQ语法,只是构造了“查询语句”,真正执行这种语句的是IEnumerator<T>里的GetEnumerator()方法,因此,当调用GetEnumerator(),就真正执行一次LinQ获取数据,多次调用GetEnumerator(),就多次执行LinQ。我们可以中途修改LinQ(即修改了“查询语句”),下次执行GetEnumerator()方法的结果就会相应地改变了。
例如
List<Employee> emps = new List<Employee>() { new Employee(){ id="1001", name="ivan", dept="isd", tel="1021"}, new Employee(){ id="1002", name="ivan", dept="isd", tel="1021"}, }; var query = from e in emps select e; emps.Add(new Employee(){ id="1003", name="ivan", dept="isd", tel="1021"}); Console.WriteLine(query.Count()); //输出结果: 3
2、可以为相同的容器多次应用相同的Linq查询,而始终获得最新的结果。
3、可以使用Linq延迟执行将额外信息的检索操作延迟到你确实需要检索它们时再进行。
二、linq延迟执行的影响
1、重复执行
当我们重复遍历查询结果时,查询会被重复执行
static void TestReevaluation()
{
var numbers = new List<int>() { 1, 2 };
IEnumerable<int> query = numbers.Select(n => n * 10); // Build query
foreach (int n in query) Console.Write(n + "|"); // 10|20|
numbers.Clear();
foreach (int n in query) Console.Write(n + "|"); // <nothing>
}
有时候,重复执行对我们说可不是一个优点,理由如下:
(1)、当我们需要在某一个给定的点保存查询的结果时。
(2)、有些查询比较耗时,比如在对一个非常大的sequence进行查询或者从远程数据库获取数据时,为了性能考量,我们并不希望一个查询会被反复执行。
这个时候,我们就可以利用转换运算符,比如ToArray、ToList来避开重复执行,ToArray把查询结果保存至一个Array,而ToList把结果保存至泛型List<>
static void TestDefeatReevaluation()
{
var numbers = new List<int>() { 1, 2 };
List<int> timesTen = numbers
.Select(n => n * 10)
.ToList(); // Executes immediately into a List<int>
numbers.Clear();
Console.Write(timesTen.Count); // Still 2
}
2、变量捕获
如果查询的lambda表达式引用了程序的局部变量时,查询会在执行时对变量进行捕获。这意味着,如果在查询定义之后改变了该变量的值,那么查询结果也会随之改变。
static void TestCapturedVariable()
{
int[] numbers = { 1, 2 };
int factor = 10;
IEnumerable<int> query = numbers.Select(n => n * factor);
factor = 20;
foreach (int n in query)
Console.Write(n + "|"); // 20|40|
}
三、如何让Linq查询立即执行呢
Enumerable定义了诸如ToArray<T>()、ToDictionary<TSource, TKey>()、ToList<T>()在内的许多扩展方法,它们允许我们以强类型容器来捕获Linq查询结果。
由于每调用一次GetEnumerator(),就执行一次LinQ,在“查询语句”不变的情况下,就会出现多次重复的查询操作(结果一样),这种情况下,有必要使用ToList(),ToArray()这样的方法把结果固定下来(其实也就是调用GetEnumerator方法返回结果来装载List,Array),然后操作相应的List,Array,避免重复的查询操作。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestVar
{
class Program
{
static void Main(string[] args)
{
int[] intAry = new int[] { 1, 2, 3, 4, 5, 6 }; //使用强类型立即获取查询结果
List<int> intList = (from x in intAry
where x % 2 == 0
select x).ToList(); //输出查询结果 foreach (int v in intList)
{
Console.Write(v.ToString() + " ");
}
Console.ReadKey();
}
}
}
- linq not in 查询
- linq中AsEnumerable和AsQueryable的区别
- 使用 LINQPad 调试linq以及lambda表达式
- linq中let
- datatable linq查询
- linq xml 查询
- linq中group by
- linq distinct去重
- linq中延迟执行
- Linq中的TakeWhile和SkipWhile
- LINQ TO SQL 中join
- Linq操作Datable
- linq 排序
- Linq中select查询
- 如何查看linq生成的sql
- linq to sql 中Concat、Union、Intersect、Except
- 吴彦祖陈冠希 恩怨 ,失去曾让他流泪的女友,终遇走过18年真爱(吴彦祖陈冠希恩怨)
- 痴情男神 吴彦祖 与妻子恋爱8年,结婚10年,家庭幸福美满(痴情男神吴彦祖)
- 成功破圈,小牛电动SQi强势开 跨(小牛电动SQi强势开)
- 挑战新国标电自天花板,九号机械师MMAX 110P深度体验(挑战新国标电自天花板)
- 《满江红》不要只当电影看,学生应该这样做(满江红不要只当电影看)
- 电影《民间怪谈录之走阴人》定档8月5日,开启一场中式惊悚之旅(电影民间怪谈录之走阴人定档8月5日)
热门推荐
- sql数据库安装概要(详解将DataGrip连接到MS SQL Server的方法)
- phpsetcookie参数说明(PHP的cookie与session原理及用法详解)
- 如何查看python是否安装selenium(selenium+python截图不成功的解决方法)
- apachemodule定义(使ApacheBench支持multi-url的方法)
- 如何提升代码质量
- uni app开发教程(uniapp+Html5端实现PC端适配)
- mysql千万数据如何优化(MySQL千万级数据的表如何优化)
- python 获取ip mac 地址(Python3获取电脑IP、主机名、Mac地址的方法示例)
- mysql 删除数据回收空间(浅谈为什么MySQL不建议delete删除数据)
- Sql Server事务日志