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 查询转换为扩展方法,所以结果与前面的相同。

    冯瑞涛
  • 相关阅读:
    svn服务器安装
    查看IIS应用程序池的运行状况
    Microsoft Web Farm Framework 和 server Farms
    Subversion 错误信息一览表
    LINUX 时间和日期
    DiskGenius的 “终止位置参数溢出”错误解决方法。
    TortoiseSVN在网盘显示图标的设置
    配置GDB以支持查看stl容器数据
    TortoiseSVN,排除不想提交文件的方法
    win7系统 设置宽带连接网络共享 出现错误 无法启用共享访问 错误代码:0x80004005:未指定错误
  • 原文地址:https://www.cnblogs.com/finehappy/p/1578572.html
Copyright © 2011-2022 走看看