.NET基础学习(LINQ)

系统 1477 0

转: http://www.cnblogs.com/cmsdn/archive/2012/04/12/2442107.html

什么是LINQ

  • LINQ(发音为link)代表语言集成查询(Language Integrated Query)
  • 详细见 LINQ

匿名类型

第一个成员初始化器是赋值形式,第二个是成员访问表达式,第三个是标示符形式,如下实例所示:

      
        1
      
      
        string
      
       Sex = 
      
        "
      
      
      
        "
      
      
        ;

      
      
        2
      
      
        var
      
       person = 
      
        new
      
       { Age = 
      
        24
      
      
        , SimpleClass.Name, Sex };

      
      
        3
      
       Console.WriteLine(
      
        "
      
      
        {0},Sex{1},Age {2}
      
      
        "
      
      ,person.Name,person.Sex,person.Age);
    

运行结果:

注意标示符形式和访问表达式必须定义在匿名类型申明之前,Sex是一个局部变量,Name是类SimpleClass的静态字段。

尽管在代码中看不到匿名类型,对象浏览器却能看到。如果编译器遇到了另一个具有相同参数名、相同引用类型名和相同顺序的匿名类型,它会重用这个类型并直接创建新的实例,而不会创建新的匿名类型。

查询语法和方法语法

  • 查询语法(query syntax)是声明形式的,看上去和SQL的语句很相似。查询语法使用查询表达式书写。
  • 方法语法(method syntax)是命令形式,它的使用是标准的方法调用。方法是一组叫做标准查询运算符的方法。
  • 在一个查询中也可以组合以上两种形式。

示例代码如下所示:

      
         1
      
      
        var
      
       query1 = 
      
        from
      
       n 
      
        in
      
       Enumerable.Range(
      
        1
      
      , 
      
        10
      
      
        )

      
      
         2
      
      
        where
      
       n < 
      
        8
      
      
         3
      
      
        select
      
      
         n;

      
      
         4
      
       Console.Write(
      
        "
      
      
        查询语法得到结果:
      
      
        "
      
      
        );

      
      
         5
      
      
        foreach
      
       (
      
        var
      
       v 
      
        in
      
       query1) Console.Write(
      
        "
      
      
        {0}\t
      
      
        "
      
      
        ,v);

      
      
         6
      
      
         7
      
      
        var
      
       query2 = Enumerable.Range(
      
        1
      
      , 
      
        8
      
      ).Where(n => n < 
      
        8
      
      
        );

      
      
         8
      
       Console.WriteLine(
      
        ""
      
      
        );

      
      
         9
      
       Console.Write(
      
        "
      
      
        方法语法得到结果:
      
      
        "
      
      
        );

      
      
        10
      
      
        foreach
      
       (
      
        var
      
       v 
      
        in
      
       query2) Console.Write(
      
        "
      
      
        {0}\t
      
      
        "
      
      
        , v);

      
      
        11
      
      
        12
      
      
        int
      
       count = (
      
        from
      
       n 
      
        in
      
       Enumerable.Range(
      
        1
      
      , 
      
        10
      
      
        )

      
      
        13
      
      
        where
      
       n < 
      
        8
      
      
        14
      
      
        select
      
      
         n).Count();

      
      
        15
      
       Console.WriteLine(
      
        ""
      
      
        );

      
      
        16
      
       Console.WriteLine(
      
        "
      
      
        两种方式的组合:{0}
      
      
        "
      
      , count);
    

运行结果:

查询表达式的结构

1、from子句

  • from子句指定了要作为数据源使用的数据集合。它也引入了迭代变量,迭代变量有序表示数据源的每一个元素。
      
        1
      
      
        int
      
      [] arr = { 
      
        1
      
      , 
      
        5
      
      , 
      
        9
      
      , 
      
        8
      
      , 
      
        45
      
      , 
      
        23
      
      , 
      
        26
      
      , 
      
        14
      
      , 
      
        7
      
      , 
      
        8
      
      , 
      
        9
      
      
         };

      
      
        2
      
      
        var
      
       query = 
      
        from
      
       n 
      
        in
      
       arr 
      
        //
      
      
        (n->迭代变量)
      
      
        3
      
      
        where
      
       n < 
      
        10
      
      
        //
      
      
        使用迭代变量
      
      
        4
      
      
        select
      
       n; 
      
        //
      
      
        使用迭代变量
      
      
        5
      
      
        foreach
      
       (
      
        var
      
       v 
      
        in
      
       query) Console.Write(
      
        "
      
      
        {0}\t
      
      
        "
      
      
        ,v);

      
      
        6
      
       Console.WriteLine(
      
        ""
      
      );
    

运行结果:

2、join子句

  • LINQ中的join子句和SQL中的join很相似,连接操作接受两个集合然后创建一个临时的对象集合,每个对象包含原始集合对象中的所有字段,使用连接来结合两个或更多个集合中的数据。

示例代码如下:

      
         1
      
      
        public
      
      
        class
      
      
         Student

      
      
         2
      
      
         {

      
      
         3
      
      
        public
      
      
        int
      
      
         StID;

      
      
         4
      
      
        public
      
      
        string
      
      
         LastName;

      
      
         5
      
      
         }

      
      
         6
      
      
        public
      
      
        class
      
      
         CourseStudent

      
      
         7
      
      
         {

      
      
         8
      
      
        public
      
      
        string
      
      
         CourseName;

      
      
         9
      
      
        public
      
      
        int
      
      
         StID;

      
      
        10
      
      
         }

      
      
        11
      
      
        12
      
       CourseStudent[] studentInCourses = 
      
        new
      
      
         CourseStudent[]{

      
      
        13
      
      
        new
      
       CourseStudent{CourseName=
      
        "
      
      
        Art
      
      
        "
      
      ,StID=
      
        1
      
      
        },

      
      
        14
      
      
        new
      
       CourseStudent{CourseName=
      
        "
      
      
        Art
      
      
        "
      
      ,StID=
      
        3
      
      
        },

      
      
        15
      
      
        new
      
       CourseStudent{CourseName=
      
        "
      
      
        History
      
      
        "
      
      ,StID=
      
        1
      
      
        },

      
      
        16
      
      
        new
      
       CourseStudent{CourseName=
      
        "
      
      
        History
      
      
        "
      
      ,StID=
      
        2
      
      
        },

      
      
        17
      
      
        new
      
       CourseStudent{CourseName=
      
        "
      
      
        Physics
      
      
        "
      
      ,StID=
      
        3
      
      
        }

      
      
        18
      
      
         };

      
      
        19
      
       Student[] students = 
      
        new
      
      
         Student[] {

      
      
        20
      
      
        new
      
       Student{StID=
      
        1
      
      ,LastName=
      
        "
      
      
        张三
      
      
        "
      
      
        },

      
      
        21
      
      
        new
      
       Student{StID=
      
        2
      
      ,LastName=
      
        "
      
      
        李四
      
      
        "
      
      
        },

      
      
        22
      
      
        new
      
       Student{StID=
      
        3
      
      ,LastName=
      
        "
      
      
        王五
      
      
        "
      
      
        }

      
      
        23
      
      
         };

      
      
        24
      
      
        25
      
      
        //
      
      
        获取选修2门课以上同学的名字
      
      
        26
      
      
        var
      
       query = (
      
        from
      
       s 
      
        in
      
      
         students

      
      
        27
      
       join c 
      
        in
      
      
         studentInCourses on s.StID equals c.StID

      
      
        28
      
      
        where
      
       (
      
        from
      
       x 
      
        in
      
       studentInCourses 
      
        where
      
       x.StID==c.StID 
      
        select
      
       x.StID).Count()>
      
        1
      
      
        29
      
      
        select
      
      
         s.LastName).Distinct();

      
      
        30
      
      
        foreach
      
       (
      
        var
      
       v 
      
        in
      
       query) Console.Write(
      
        "
      
      
        {0}\t
      
      
        "
      
      
        ,v);

      
      
        31
      
       Console.WriteLine(
      
        ""
      
      
        );

      
      
        32
      
      
        //
      
      
        获取选修历史同学的名字
      
      
        33
      
      
        var
      
       query1 = 
      
        from
      
       s 
      
        in
      
      
         students

      
      
        34
      
       join c 
      
        in
      
      
         studentInCourses on s.StID equals c.StID

      
      
        35
      
      
        where
      
       c.CourseName == 
      
        "
      
      
        History
      
      
        "
      
      
        36
      
      
        select
      
      
         s.LastName;

      
      
        37
      
      
        foreach
      
       (
      
        var
      
       v 
      
        in
      
       query1) Console.Write(
      
        "
      
      
        {0}\t
      
      
        "
      
      , v);
    

运行结果:

查询主体中的from...let...where片段

  • 可选的from...let...where部分是查询主体的第一部分,可以由任意数量的3个子句来组合--from子句、let子句和where子句。

1、from子句

  • 查询表达式必须从from子句开始,后面跟的是查询主体。主体本身可以从任何数量的其他from子句开始,每一个from子句都指定了一个额外的数据源集合并引入了要在之后运算的迭代变量,所有from子句的语法和含义都是一样的。

示例代码如下:

      
        1
      
      
        var
      
       someInts = 
      
        from
      
       a 
      
        in
      
       Enumerable.Range(
      
        1
      
      , 
      
        5
      
      ) 
      
        //
      
      
        必须的第一个from子句
      
      
        2
      
      
        from
      
       b 
      
        in
      
       Enumerable.Range(
      
        6
      
      , 
      
        5
      
      ) 
      
        //
      
      
        查询主体的第一个子句
      
      
        3
      
      
        where
      
       a < 
      
        3
      
       && b < 
      
        10
      
      
        4
      
      
        select
      
      
        new
      
       { a, b, sum = a + b }; 
      
        //
      
      
        匿名类型对象
      
      
        5
      
      
        foreach
      
       (
      
        var
      
       v 
      
        in
      
       someInts) Console.WriteLine(v);
    

2、let子句

  • let子句接受一个表达式的运算并把它赋值给一个需要在其他运算中使用的标示符。

示例代码如下:

      
        1
      
      
        var
      
       someInts = 
      
        from
      
       a 
      
        in
      
       Enumerable.Range(
      
        1
      
      , 
      
        5
      
      
        )

      
      
        2
      
      
        from
      
       b 
      
        in
      
       Enumerable.Range(
      
        6
      
      , 
      
        5
      
      
        )

      
      
        3
      
       let sum = a + b 
      
        //
      
      
        在新的变量中保存结果
      
      
        4
      
      
        where
      
       sum == 
      
        12
      
      
        5
      
      
        select
      
      
        new
      
      
         { a, b, sum };

      
      
        6
      
      
        foreach
      
       (
      
        var
      
       v 
      
        in
      
       someInts) Console.WriteLine(v);
    

运行结果:

.NET基础学习(LINQ)

3、where子句

  • where子句根据之后的运算来去除不符合指定条件的项。

示例代码如下:

      
        1
      
      
        var
      
       someInts = 
      
        from
      
       a 
      
        in
      
       Enumerable.Range(
      
        1
      
      , 
      
        5
      
      
        )

      
      
        2
      
      
        from
      
       b 
      
        in
      
       Enumerable.Range(
      
        6
      
      , 
      
        5
      
      
        )

      
      
        3
      
       let sum = a +
      
         b

      
      
        4
      
      
        where
      
       sum > 
      
        12
      
      
        //
      
      
        条件一
      
      
        5
      
      
        where
      
       a==
      
        4
      
      
        //
      
      
        条件二
      
      
        6
      
      
        select
      
      
        new
      
      
         { a, b, sum };

      
      
        7
      
      
        foreach
      
       (
      
        var
      
       v 
      
        in
      
       someInts) Console.WriteLine(v);
    

运行结果:

orderby子句

  • orderby子句接受一个表达式并根据表达式依次返回结果项,orderby子句的默认排序是升序,然而我们可以使用ascending和descending关键词显示第设置元素排序为升序或降序,ordery可以有任意多个子句,它们必须用逗号隔开。

示例代码如下:

      
         1
      
      
        var
      
       persons = 
      
        new
      
      [] { 
      
        //
      
      
        匿名类型的对象数组
      
      
         2
      
      
        new
      
       {Name=
      
        "
      
      
        张三
      
      
        "
      
      ,Sex=
      
        "
      
      
      
        "
      
      ,Age=
      
        32
      
      ,Address=
      
        "
      
      
        广东深圳
      
      
        "
      
      
        },

      
      
         3
      
      
        new
      
       {Name=
      
        "
      
      
        李四
      
      
        "
      
      ,Sex=
      
        "
      
      
      
        "
      
      ,Age=
      
        26
      
      ,Address=
      
        "
      
      
        广东广州
      
      
        "
      
      
        },

      
      
         4
      
      
        new
      
       {Name=
      
        "
      
      
        王五
      
      
        "
      
      ,Sex=
      
        "
      
      
      
        "
      
      ,Age=
      
        22
      
      ,Address=
      
        "
      
      
        广东深圳
      
      
        "
      
      
        },

      
      
         5
      
      
        new
      
       {Name=
      
        "
      
      
        赵六
      
      
        "
      
      ,Sex=
      
        "
      
      
      
        "
      
      ,Age=
      
        33
      
      ,Address=
      
        "
      
      
        广东东莞
      
      
        "
      
      
        }

      
      
         6
      
      
         };

      
      
         7
      
      
        var
      
       query = 
      
        from
      
       p 
      
        in
      
      
         persons

      
      
         8
      
      
        orderby
      
      
         p.Age

      
      
         9
      
      
        select
      
      
         p;

      
      
        10
      
      
        foreach
      
       (
      
        var
      
       p 
      
        in
      
       query) Console.WriteLine(
      
        "
      
      
        Name:{0},Sex:{1},Age:{2},Address:{3}
      
      
        "
      
      , p.Name, p.Sex, p.Age, p.Address);
    

运行结果:

.NET基础学习(LINQ)

group by子句

  • group子句把select的对象根据一些标准进行分组。例如,有了前面示例人的数组,程序可以根据它们的所在地进行分组。
  • group by如果项包含在查询结果中,它们就可以根据某个字段的值进行分组。作为分组依据的项叫做键(key);和select子句不同,group子句不从原始的数据源中返回可枚举的可枚举类型,而是返回以枚举已经形成的项的分组的可枚举类型;分组本身是可枚举类型,它们可枚举实际的项。

示例代码如下:

      
         1
      
      
        var
      
       persons = 
      
        new
      
      [] { 
      
        //
      
      
        匿名类型的对象数组
      
      
         2
      
      
        new
      
       {Name=
      
        "
      
      
        张三
      
      
        "
      
      ,Sex=
      
        "
      
      
      
        "
      
      ,Age=
      
        32
      
      ,Address=
      
        "
      
      
        广东深圳
      
      
        "
      
      
        },

      
      
         3
      
      
        new
      
       {Name=
      
        "
      
      
        李四
      
      
        "
      
      ,Sex=
      
        "
      
      
      
        "
      
      ,Age=
      
        26
      
      ,Address=
      
        "
      
      
        广东广州
      
      
        "
      
      
        },

      
      
         4
      
      
        new
      
       {Name=
      
        "
      
      
        王五
      
      
        "
      
      ,Sex=
      
        "
      
      
      
        "
      
      ,Age=
      
        22
      
      ,Address=
      
        "
      
      
        广东深圳
      
      
        "
      
      
        },

      
      
         5
      
      
        new
      
       {Name=
      
        "
      
      
        赵六
      
      
        "
      
      ,Sex=
      
        "
      
      
      
        "
      
      ,Age=
      
        33
      
      ,Address=
      
        "
      
      
        广东东莞
      
      
        "
      
      
        }

      
      
         6
      
      
         };

      
      
         7
      
      
        var
      
       query = 
      
        from
      
       p 
      
        in
      
      
         persons

      
      
         8
      
      
         group p by p.Address;

      
      
         9
      
      
        foreach
      
       (
      
        var
      
       v 
      
        in
      
       query) 
      
        //
      
      
        枚举分组
      
      
        10
      
      
         {

      
      
        11
      
       Console.WriteLine(
      
        "
      
      
        {0}
      
      
        "
      
      ,v.Key); 
      
        //
      
      
        分组键
      
      
        12
      
      
        foreach
      
       (
      
        var
      
       t 
      
        in
      
       v) 
      
        //
      
      
        枚举分组中的项
      
      
        13
      
      
         {

      
      
        14
      
       Console.WriteLine(
      
        "
      
      
        Name:{0},Sex:{1},Age:{2},Address:{3}
      
      
        "
      
      
        , t.Name, t.Sex, t.Age, t.Address);

      
      
        15
      
      
         }

      
      
        16
      
       }
    

运行结果:

.NET基础学习(LINQ)

查询延续

  • 查询延续子句可以接受查询的一部分结果并赋予一个名字,从而可以查询的另一部分中使用。

示例代码如下:

      
        1
      
      
        var
      
       somInts = 
      
        from
      
       a 
      
        in
      
       Enumerable.Range(
      
        1
      
      , 
      
        10
      
      
        )

      
      
        2
      
       join b 
      
        in
      
       Enumerable.Range(
      
        5
      
      , 
      
        10
      
      
        ) on a equals b

      
      
        3
      
       into groupTemp 
      
        //
      
      
        查询延续
      
      
        4
      
      
        from
      
       c 
      
        in
      
      
         groupTemp

      
      
        5
      
      
        select
      
      
         c;

      
      
        6
      
      
        foreach
      
       (
      
        var
      
       v 
      
        in
      
       somInts) Console.WriteLine(v);
    

运行结果如下:

.NET基础学习(LINQ)

使用委托参数和Lambda的示例

public static int Count<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);

示例代码如下:

      
        1
      
       IList<
      
        int
      
      > list = Enumerable.Range(
      
        1
      
      , 
      
        100
      
      
        ).ToList();

      
      
        2
      
       Func<
      
        int
      
      , 
      
        bool
      
      > myDel = 
      
        delegate
      
      (
      
        int
      
       x) { 
      
        return
      
       x % 
      
        2
      
       == 
      
        1
      
      ; };
      
        //
      
      
        委托匿名方法
      
      
        3
      
      
        var
      
       countOdd1 = list.Count(myDel);
      
        //
      
      
        调用委托
      
      
        4
      
      
        var
      
       countOdd2 = list.Count(x => x % 
      
        2
      
       == 
      
        1
      
      );
      
        //
      
      
        Lambda表达式
      
      
        5
      
       Console.WriteLine(
      
        "
      
      
        委托参数得到奇数的个数:{0}
      
      
        "
      
      
        ,countOdd1);

      
      
        6
      
       Console.WriteLine(
      
        "
      
      
        Lambda得到奇数的个数:{0}
      
      
        "
      
      , countOdd2);
    

运行结果:

.NET基础学习(LINQ)

版权所有,转载请注明出处!

.NET基础学习(LINQ)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论