`
terryfeng
  • 浏览: 492228 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

分享到:
评论

相关推荐

    C#5.0本质论第四版(因文件较大传的是百度网盘地址)

    第14章 支持标准查询操作符的集合接口 385 14.1 匿名类型和隐式类型的局部变量声明 386 14.1.1 匿名类型 386 14.1.2 隐式类型的局部变量 387 14.1.3 匿名类型和隐式局部变量的更多注意事项 388 ...

    轻松学C#(图解版)

    第三篇是应用技术篇,主要介绍的是异常处理、文件和流、委托、事件、Lambda表达式、命名空间、预处理器、程序集、运行时类型标识、反射、特性、泛型、LINQ和数据库开发等。 =======================================...

    C# 程序设计手册(WORD)

    在 C# 中撰写 LINQ 查询 336 查询对象集合 339 从方法传回查询 341 将查询的结果储存在内存中 343 使用各种不同方式分组结果 344 将群组包含在群组中 352 针对分组作业执行子查询 353 在运行时间动态指定述词筛选...

    C#并行编程高级教程:精通.NET 4 Parallel Extensions中文(第一部分)

    6.1.2 AsOrdered和orderby子句 6.2 指定执行模式 6.3 理解PLINQ中的数据分区 6.4 通过PLINQ执行归约操作 6.5 创建自定义的PLINQ聚合函数 6.6 并发PLINQ任务 6.7 取消PLINQ 6.8 指定所需的并行度 6.8.1 ...

Global site tag (gtag.js) - Google Analytics