Linq延迟执行

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/

上一篇:switch判断计算器


下一篇:Python基础操作