zoukankan      html  css  js  c++  java
  • LINQ 标准的查询操作符 复合的 from 子句

    复合的  from 子句

    如果需要根据对象的一个成员进行过滤,而该成员本身是一个集合,就可以使用复合的 from 子句。

    Racer 类定义了一个属性 Cars, Cars  是一个字符串数组。

    要过滤驾驶 Ferrari  的所有冠军, 可以使用如下所示的 LINQ 查询。

    第一个 from  子句访问从 Formyla1.GetChampions()返回的Racer  对象,

    第二个 from  子句访问 Racer 类的属性 Cars,返回所有的string  类型的赛车。

    接着在 Where  子句中使用这些赛车过滤驾驶 Ferrari 的所有车手

    并使用LastName升序

    private static void CompoundFrom()
            {
                var fd = from r in Formula1.GetChampions()
                         from c in r.Cars
                         where c == "Ferrari"
                         orderby r.LastName
                         select r.FirstName + " " + r.LastName;
    
                foreach (var racer in fd)
                {
                    Console.WriteLine(racer);
                }
            }
    结果把Cas中带有Ferrari 的9个车手名字列了出来:

    image

    C#编译器把复合的 from 子句和 LINQ  查询转换为 SelectMany()扩展方法。SelectMany()可用于迭代集合
    中的集合。示例中 SelectMany()方法的重载版本如下所示:

    public static IEnumerable < TResult > SelectMany < TSource, TCollection, TResult > (

    this IEnumerable < TSource > source,
    Func < TSource, IEnumerable < TCollection > > collectionSelector,
    Func < TSource, TCollection, TResult > resultSelector);

    下面的程序就是调用这个扩展方法,说明如下:
    1.第一个参数是隐式参数,从 GetChampions()方法中接收 Racer 对象序列。

    2.第二个参数(r => r.Cars)是 collectionSelector 委托,它定义了内部集合。在λ表达式r=>r.Cars  中,应返回赛车集合。r 本身是R集合,用这个又得到了Cars集合

    3.第三个参数是一个委托,现在为每个赛车调用该委托,接收 Racer 和 Car 对象。

    4.λ表达式创建了一个匿名类型,它带 Racer1  和 Car1  属性。匿名对象的 Racer1属性附上了r,Car1属性附上了c,属性名随意定的

    5.这个SelectMany()方法的结果是摊平了赛手和赛车的层次结构,

    5.为每辆赛车返回匿名类型的一个新对象集合。

    这个新集合传送给Where()方法,过滤出驾驶 Ferrari  的赛手。最后,调用OrderBy()和Select()方法:

    /// <summary>
            /// 复合的from子句
            /// </summary>
            private static void CompoundFrom()
            {
                var fd = Formula1.GetChampions().
                    SelectMany( r => r.Cars, (r, c) => new { Racer1 = r, Car1 = c }).
                      Where(r => r.Car1 == "Ferrari").
                      OrderBy(r => r.Racer1.LastName).
                      Select(r => r.Racer1.FirstName + " " + r.Racer1.LastName);
                foreach (var racer in fd)
                {
                    Console.WriteLine(racer);
                }
    
    
            }

    结果和上面一样

    把 SelectMany()泛型方法解析为这里使用的类型,所解析的类型如下所示。

    在这个例子中,数据源是 Racer 类型,所过滤的集合是一个string  数组,当然所返回的匿名类型的名称是未知的,

    这里显示为 TResult:

    public static IEnumerable < TResult > SelectMany < Racer, string, TResult > (
    this IEnumerable < Racer > source,   //Formula1.GetChampions()的结果
    Func < Racer, IEnumerable < string > > collectionSelector,  // SelectMany( r => r.Cars,中的 r => r.Cars, 返回结果集为 IEnumerable < string >
    Func < Racer, string, TResult > resultSelector);  //(r, c) => new { Racer1 = r, Car1 = c }).   // r, c, => new {} 返回结果为
    TResult 到r 表达式左式的第一个参数r

    查询仅从 LINQ 查询转换为扩展方法,所以结果与前面的相同。

    冯瑞涛
  • 相关阅读:
    表的转置 行转列: DECODE(Oracle) 和 CASE WHEN 的异同点
    Sql中EXISTS与IN的使用及效率
    Oracle学习之start with...connect by子句的用法
    Java复制、移动和删除文件
    简单的实现微信获取openid
    SQL语句中LEFT JOIN、JOIN、INNER JOIN、RIGHT JOIN的区别?
    java 基础最全网站
    SpringBoot(十一)过滤器和拦截器
    做项目遇到的问题集锦
    使用Java实现二叉树的添加,删除,获取以及遍历
  • 原文地址:https://www.cnblogs.com/finehappy/p/1578572.html
Copyright © 2011-2022 走看看