zoukankan      html  css  js  c++  java
  • 【总结】LINQ查询基本操作列表

    每个LINQ查询都以from子句开始,from子句包括以下两个功能。

    • 指定查询将采用数据源。
    • 定义一个本地变量,表示数据源中单个元素

    复制代码
                string[] values = { "中国", "日本", "美国", "菲律宾", "越南" };
    
                //查询包含“国”的字符串
                var valueQuery = from v in values
                                 where v.IndexOf("国") > 0
                                 select v;
    
                foreach (var v in valueQuery)
                {
                    Console.WriteLine("{0,1}", v);
                }
    复制代码

    在这个LINQ表达式的from子句中,v叫做范围变量,values是数据源。v的作用域存在于当前的LINQ表达式,表达式以外不能访问这个变量。where用来筛选元素,select用于输出元素。这里的范围变量v,和foreach语句中得隐式变量v都可以由编译器推断出其类型。
    运行的结果如下:

    中国
    美国

    1、如何使用LINQ

            LINQ作为一种数据查询编码方式,本身并不是独立的开发语句,也不能进行应用程序开发。在.NET3.5中,可以在C#中集成LINQ查询代码。在任何源代码文件中,要使用LINQ查询功能,必须引用System.Linq命名空间。使用LINQ to XML要引用System.Xml.Linq命名空间,使用LINQ to ADO.NET要引用System.Data.Linq命名空间。


    2、LINQ查询表达式

            查询表达式关键字:

        from:指定要查找的数据源以及范围变量,多个from子句则表示从多个数据源中查找数据

        select: 指定查询要返回的目标数据,可以指定任何类型,甚至是匿名类型

        where: 指定元素的筛选条件,多个where子句则表示了并列关系,必须全部都满足才能入选

        orderby: 指定元素的排序字段和排序方式,当有多个排序字段时,有字段顺序确定主次关系,可以指定升序和降序两种排序方式

        group: 指定元素的分组字段

        join: 指定多个数据源的关联方式


    2.1 用from子句指定数据源

      每个LINQ查询语句都是以from子句开始,from子句包括以下两个功能:

        ●指定查询将采用的数据源

        ●定义一个本地变量,表示数据源中的单个元素

      如: from localval in datasource

      一般情况下,不用为from子句的localval元素指定数据类型,编译器会根据数据源类型为它分配合适的类型,通常为IEnumerable<T>中的类型T。例如,下面的val会被分配为int类型

        int[] arr =  {1,2,3,4,5};

        var query = from val in arr select val; 

      特殊情况下,开发人员需要为本地变量指定数据类型,比如上面的例子中,如果希望将arr中的元素作为object类型进行处理,而不是int类型,需要指定val2为object类型,因为arr中元素是int类型,数据object类型的子类型,所以可以直接转换,如下:

        int[] arr =  {1,2,3,4,5};

        var query = from object val2 in arr select val2;

      值得注意的是,编译器并不会检查本地变量的具体类型,所以即使指定类型不正确,编译器也不会报错,但是在下面使用该查询时,会在运行时进行类型检查,从而产生异常。


    2.2 用select子句指定目标数据

      LINQ查询表达式必须以select或者group子句结束。select子句中要选择的目标数据不仅可以是数据源中的元素,还可以是该元素的不同操作结果,包括属性、方法、运算,如下面两个例子:   

    复制代码
    var query2 =
                    from val in arr
                    select val.Name;
                foreach(string item in query2)
                {
                    Console.Write("{0},   ",item);
                }
                Console.WriteLine();
                var query3 =
                    from val in arr
                    select val.Name.Length;
                foreach (int item in query3)
                {
                    Console.Write("{0},   ", item);
                }
    复制代码

      在某些特殊的场合,往往查询结果只是临时使用一下,而且查询结果的数据包括很多字段,并非简单的一个属性、方法返回值等。在LINQ中,可以在select子句中使用匿名类型来解决这个问题。如query4中的select子句通过匿名类型定义返回结果,因为编码无法使用匿名类型,所以在foreach只能通过var(可变类型)关键字让编译器自动判断查询中元素类型。

    复制代码
                var query4 =
                    from val in arr
                    select new { val.Name, val.Age,  NameLen = val.Name.Length};
                foreach(var item2 in query4)
                {
                    Console.WriteLine(item2);
                }            
    复制代码

    2.3 用where子句指定筛选条件

       作用:指定查询的过滤条件

      格式:where Expression

      int[] ary = {1,2,3,4,5,6,7,8,9,10,11,12};

      var query =

            from val in ary

            where (val > 5) && (val < 10)

            select val;


    2.4 用orderby子句进行排序

       作用:对查询结果进行排序

      格式: orderby element [sortType]

      其中,sortType是可选参数,表示排序类型,包括升序(ascending)和降序(descending)两个参数,默认为升序。

    复制代码
                int[] ary = { 9,54,32,1,67,43,0,9,7,4,9,2,23,66,61};
                var query5 =
                    from val in ary
                    orderby val
                    select val;
                foreach(var item in query5)
                {
                    Console.Write("{0}   ",item);
                }
                Console.WriteLine();
                Console.WriteLine();
                var query6 =
                    from val in ary
                    orderby val descending
                    select val;
                foreach (var item in query6)
                {
                    Console.Write("{0}   ", item);
                }
    复制代码

    结果是:

       

      在LINQ中,orderby可以同时指定多个排序元素,也可以为每个排序元素指定独立的排序方式。orderby后的第一个排序元素为主要排序,第二个为次要排序,依次类推。如下面例子,先按照姓名字符数量进行升序排列,再按照年龄降序排列。 

    复制代码
                var query7 =
                    from val in arr
                    orderby val.Name.Length ascending, val.Age descending
                    select val;
                foreach(var item in query7)
                {
                    Console.WriteLine(item);
                }
    复制代码

    结果:


    2.5 用group子句进行分组

       作用:对数据进行分组

      格式:group element by key

    复制代码
                var query8 =
                    from val in arr
                    group val by val.Xingbie;
                foreach(var grp in query8)
                {
                    Console.WriteLine(grp.Key);
                    foreach(var st in grp)
                    {
                        Console.WriteLine("	{0}",st);
                    }
                }
    复制代码

      有时候需要对分组结果进行排序、在查询等操作,这时候就需要使用into 关键字将group查询结果存在一个临时变量中,并且必须使用新的select或者group子句对其进行查询,也可使用orderby进行排序,where进行过滤等等,into的语句格式如下

        group element by key into tmpgrp

      其中,tmpgrp就是临时变量,用来临时保存group产生的结果,提供后面的查询操作。

    复制代码
                var query9 =
                    from val in arr
                    group val by val.Age into stgrp
                    orderby stgrp.Key descending
                    select stgrp;
                foreach(var st in query9)
                {
                    Console.WriteLine("{0}岁的学生:",st.Key);
                    foreach(var stu in st)
                    {
                        Console.WriteLine("	{0}",stu);
                    }
                }
    复制代码


    2.6 用join子句进行关联

       join子句实现联接操作,将来自不同源序列,并且在对象模型中没有直接关系的元素相关联,唯一的要求就是每个源中的元素需要共享某个可以进行比较,以判断是否相等的值。

      join子句可以实现3种类型的联接: 内部联接、分组联接、左外部联接。


    2.6.1 用join子句进行内部联接

      格式: join element in datasource on exp1 equals exp2

      datasource 表示数据源,它是联接要使用的第二个数据集,element 表示存储datasource中元素的本地变量,exp1 和 exp2 表示两个表达式,它们具有相同的数据类型,可以用equals进行比较,如果exp1 和 exp2 相等,则当前元素将添加到查询结果中。

    复制代码
                int[] intarray1 = { 5,15,25,30,33,40};
                int[] intarray2 = { 10,20,30,40,50,60,70,80,90,100};
                var query12 =
                    from val1 in intarray1
                    join val2 in intarray2 on val1 % 5 equals val2 % 15
                    select new { VAL1 = val1,VAL2 = val2};
                foreach(var val in query12)
                {
                    Console.WriteLine(val);
                }    
     
     
    复制代码

    2.6.2 用join子句进行分组联接

      格式:join element in datasource on exp1 equals exp2 into grpname

      into 关键字表示将这些数据分组并保存到grpname中,grpname是保存一组数据的集合。

      分组联接产生分层的数据结果,它将第一个集合中的每一个元素与第二个集合中的一组相关元素进行配对。值得注意的是,即使第一个集合中的元素在第二个集合中没有配对的元素,也会为它产生一个空的分组对象。

    复制代码
                var query13 =
                    from val1 in intarray1
                    join val2 in intarray2 on val1 % 5 equals val2 % 15 into grpName
                    select new { VAL1 = val1, VAL2 = grpName};
                foreach(var val in query13)
                {
                    Console.Write("{0}:  ",val.VAL1);
                    foreach(var obj in val.VAL2)
                    {
                        Console.Write("{0}  ",obj);
                    }
                    Console.WriteLine();
                }    
    复制代码

    请比较query12 和 query13 的运行结果的区别。


    2.6.3 用join子句进行左外部联接

       左外部联接返回第一个集合元素的所有元素,无论它是否在第二个集合中有相关元素。在LINQ中,通过对分组联接的结果调用DefaultEmpty()来执行左外部联接。

    复制代码
                var query14 =
                    from val1 in intarray1
                    join val2 in intarray2 on val1 % 5 equals val2 % 15 into grpName
                    from grp in grpName.DefaultIfEmpty()
                    select new { VAL1 = val1 , VAL2 = grp};
                foreach(var val in query14)
                {
                    Console.WriteLine(val);
                }
    复制代码

    2.7 使用let子句扩展范围变量

      用于创建查询自身的范围变量

    复制代码
    string[] strings ={
                     "I am a new Student.",
                     "You are a talent"
                     };
    
    var query = from sentences in strings
                let words = sentences.Split(' ')
                from word in words
                let w = word.ToLower()
                where w[0] == 'a' || w[0] == 'e' || w[0] == 'i' || w[0] == 'o' || 
                         w[0] == 'u'
                select word;
    
    foreach (var word in query)
    {
        Console.Write(word + ",");
    }
    复制代码

      需求:将字符串数组中的两句英文语句中所有的元音字母打头的单词输出到控制台

      分析:首先遍历字符串数组中的每个字符串,用let子句创建查询自身的范围变量words,并调用Split(' ')方法,将每个字符串中以空格分割为单词存入words变量中,然后再次使用let子句创建查询自身的范围变量word,并调用ToLower()方法,将每个单词都变为小写,最后筛选出首字母为元音的单词进行返回。

    PS:本文完整代码来自:http://www.cnblogs.com/crandy/p/4546126.html

  • 相关阅读:
    进程与线程
    HTML——部分MP4在谷歌浏览器上无法播放
    Node——用http-proxy 做反向代理服务器
    jQuery——操作复选框(checkbox) attr checked不起作用
    ionic2——开发利器之Visual Studio Code 常用插件整理
    ionic2——开发利器之Visual Studio Code 常用快捷键
    ionic2常见问题——修改应用图标及添加启动画面(官方命令行工具自动生成)
    ionic2常见问题——启动后白屏问题
    ionic2常见问题——解决下载gradle-2.14.1-all.zip太慢或失败
    ionic2常见问题——cordova使用Gradle构建下载maven太慢,使用阿里云镜像
  • 原文地址:https://www.cnblogs.com/zhangguorenmi/p/13034634.html
Copyright © 2011-2022 走看看