zoukankan      html  css  js  c++  java
  • LINQ进阶(深入理解C#)11 查询表达式和LINQ to Objects

    11.4 let 子句与透明标识符

    11.4.1 用let来进行中间计算

    这段代码运行正常,不过它调用了“可怕的” Length属性两次——一次是对用户进行排序,一次用于显示。

            var query = from user in SampleData.AllUsers
                        orderby user.Name.Length			//first 
                        select user.Name;
    
            foreach (var name in query)
            {
                Console.WriteLine("{0}: {1}", name.Length, name);	//seconed
            }
    

    这正是let子句的用武之地,它对一个表达式进行求值,并引入一个新的范围变量。不过对于每个用户只使用了一次Length属性。

            var query = from user in SampleData.AllUsers
                        let length = user.Name.Length	//only one
                        orderby length
                        select new { Name = user.Name, Length = length };
    
            foreach (var entry in query)
            {
                Console.WriteLine("{0}: {1}", entry.Length, entry.Name);
            }
    

    11.4.2 透明标识符

    我们在最后的投影中使用了两个范围变量,不过Select方法只对单个序列起作用。如何把范围变量合并在一起呢?
    答案是,创建一个匿名类型来包含两个变量,不过需要进行一个巧妙的转换,以便看起来就像在select和orderby子句中实际应用了两个参数。

    let子句为了实现目标,再一次调用了Select,并为结果序列创建匿名类型,最终创建了一个新的范围变量。

    查询表达式被转换为如下内容:

    11.5 连接

    11.5.2 使用join...into子句进行分组连接

    分组连接(group join)结果中的每个元素由

    左边序列(使用它的原始范围变量)的某个元素和右边序列的所有匹配元素的序列组成。

    后者用一个新的范围变量表示,该变量由join子句中into后面的标识符指定。

                var query = from defect in SampleData.AllDefects
                            join subscription in SampleData.AllSubscriptions
                                 on defect.Project equals subscription.Project
                                 into groupedSubscriptions
    
                            select new { Defect = defect, Subscriptions = groupedSubscriptions };
    
                foreach (var entry in query)
                {
                    Console.WriteLine(entry.Defect.Summary);
                    foreach (var subscription in entry.Subscriptions)
                    {
                        Console.WriteLine("  {0}", subscription.EmailAddress);
                    }
                }
    

    对于分组连接来说,在左边序列和结果序列之间是一对一的对应关系,即使左边序列中的某些元素在右边序列中没有任何匹配的元素,也无所谓。

    这是非常重要的,有时会用于模拟SQL的左外连接。在左边元素不匹配任何右边元素的时候,嵌入序列就是空的。与内连接一样,分组连接要对右边序列进行缓冲,而对左边序列进行流处理

    select...join into 相当于 GroupJoin.

    11.5.3 使用多个from子句进行交叉连接和合并序列

    它就像指定了多表查询的笛卡儿积。实际上,大多数时候,它正是交叉连接的用法。

                var query = from user in SampleData.AllUsers
                            from project in SampleData.AllProjects
                            select new { User = user, Project = project };
    
                foreach (var pair in query)
                {
                    Console.WriteLine("{0}/{1}",
                                      pair.User.Name,
                                      pair.Project.Name);
                }
    

    右边序列依赖于左边元素的交叉连接

    多个from 相当于 selectMany

                //11.6 两个from
                var query = from left in Enumerable.Range(1, 4)
                            from right in Enumerable.Range(11, left)
                            select new { Left = left, Right = right };
    
                foreach (var pair in query)
                {
                    Console.WriteLine("Left={0}; Right={1}", pair.Left, pair.Right);
                }
    
                //转化为标准查询操作符:selectMany
                var lambda = Enumerable.Range(1, 4).SelectMany(
                                                    left => Enumerable.Range(11, left),
                                                    (left, right) =>
                                                    new { Left = left, Right = right });
    
                foreach (var pair in lambda)
                {
                    Console.WriteLine("Left={0}; Right={1}", pair.Left, pair.Right);
                }
    
  • 相关阅读:
    深入理解ThreadLocal
    JAVA守护线程
    JAVA THREAD.JOIN方法详解
    JAVA中断机制详解
    Socket中的异常和参数设置
    WebSocket实战
    程序里面的system.out.println()输出到其他位置,不输出到tomcat控制台。
    数据库连接未关闭,conn与rs未关闭
    Ajax简单应用-购物车
    1.链表和数组的区别在哪里?
  • 原文地址:https://www.cnblogs.com/tangge/p/14642197.html
Copyright © 2011-2022 走看看