Linq的查询表达式只是一个表达式,并不存储查询结果,只有到用的时候才会去执行查询。
如用OrderBy立即进行查询,直到被 foreach 调用。
使用ToList(),ToArray()等方法可以强制立即执行(Forcing Immediate Execution)
var result = from t in teachers select t; ((List<Teacher>)teachers).Add(new Teacher { Name = "new" }); teachers.ToList().Add(new Teacher { Name = "new" }); //比较这两种方式Console.WriteLine(teachers.Count()); foreach (var item in result) { Console.WriteLine(item.Name); }
对于LINQ来说,延迟执行时非常重要的,因为它把查询的创建与查询的执行解耦了,这让我们可以向创建SQL查询那样,分成多个步骤来创建我们的LINQ查询。
优点
- 在进行多条件查询拼接时提高性能,使用最终表达式进行查询
- 获得“即时”(up-to-date)数据
var result = from t in teachers select t; if (true) { result = from r in result where r.Age > 20 select r; }
缺点
延迟执行带来的一个影响是,当我们重复遍历查询结果时,查询会被重复执行:
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> }
有时候,重复执行对我们说可不是一个优点,理由如下:
- 当我们需要在某一个给定的点保存查询的结果时。
- 有些查询比较耗时,比如在对一个非常大的sequence进行查询或者从远程数据库获取数据时,为了性能考量,我们并不希望一个查询会被反复执行。
解决:我们可以利用上面提到的ToArray、ToList方法来避开重复执行,ToArray把查询结果保存至一个Array,而ToList把结果保存至泛型List<>:
LINQ的查询执行遵循以下原则:
1、一般情况下(除了下面第三条说的情况),LINQ都是延迟执行,原因:以DLINQ为例,越晚被执行,对业务逻辑的理解就越清晰,DLINQ查询对数据库的请求压力越小。编译器对LINQ查询优化可作的事情越多。
2、由于是延迟执行,也就是调用的时候才去执行。这样调用一次就被执行一次,这样就具备了重复执行的功能,参看之前的几个重复执行的例子。而这个重复执行是不需要再此书写一边查询语句的。
3、如果查询中我们对查询结果使用了 ToArray、ToList、ToDictionary 这些转换成集合的扩展方法。使用这时候出来的对象是一个独立的集合数组,而不是LINQ查询,所以这时候不会出现多次查询,而只是一次查询。
文章转载自:软件开发平台
地址:https://www.hocode.com/