• C# LINQ用法


    一、什么是LINQ

      LINQ(读音link)代表语言集成查询(Language Integrated Query),是.NEt框架的扩展,它允许我们用SQL查询数据库的方式来查询数据的集合,使用它,你可以从数据库、程序对象的集合以及XML文档中查询数据

      下面一个简单的示例,可以查询数组中小于8的数字并输出。

      一般步骤:获取数据源、创建查询、执行查询。需要注意的是,尽管查询在语句中定义,但直到最后的foreach语句请求其结果的时候才会执行

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace LINK查询
    {
        class Program
        {
            static void Main(string[] args)
            {
                int[] number = { 2, 4, 6, 8, 10 }; //获取数据源
                IEnumerable<int> lowNum = from n in number  //创建并存储查询,不会执行操作
                                          where n < 8
                                          select n;
    
                foreach(var val in lowNum)  //执行查询
                {
                    Console.Write("{0}  ", val);
                }
    
                Console.ReadKey();
            }
        }
    }
    复制代码

      

    二、查询表达式的结构

      查询表达式由查询体后的from子句组成,其子句必须按一定的顺序出现,并且from子句和select子句这两部分是必须的。先介绍一下子句

      2.1    from子句

        from子句指定了要作为数据源使用的数据集合,它的语法是:

    1
    from Type Item in Items

        其中Type是集合中元素的类型,是可选的,因为编译器可以从集合来推断类型。  Item是迭代变量的名字。  Items是要查询的集合的名字,必须是可枚举类型的

        它和foreach比较相似,但foreach语句在遇到代码时就执行其主体,from子句什么也不执行。它创建可以执行的后台代码对象,只有在程序的控制流遇到访问查询变量的语句时才会执行

      2.2  join子句

        如果您对SQL中的join比较熟悉的话,那么LINQ中的join对你来说也不是什么难事,不熟悉的话,,当我没说。 

        我们可以使用join来结合两个或更多集合中的数据,它接受两个集合然后创建一个临时的对象集合

    var query = from s in students
                join c in course on s.SID equals c.SID

        equals用于比较相等性的字段,不能使用“==”代替,下面示例中有三个学生和三门课程,我们要做的是查找选修了历史课的学生名

    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace LINK查询
    {
        class Program
        {
            public class Student    //声明student类
            {
                public int stId;    //学生ID
                public string stuName;   //学生姓名
            }
    
            public class Course    //声明course类
            {
                public int stId;   //学生ID
                public string courseName;   //课程名
            }
    
            static Student[] students = new Student[]
            {
                new Student {stId = 1,stuName = "jack"},
                new Student {stId = 2,stuName = "taylor"},
                new Student {stId = 3,stuName = "fleming"}
            };
    
            static Course[] courses = new Course[]
            {
                new Course{stId = 1,courseName = "art"},
                new Course{stId = 2, courseName = "art"},
                new Course{stId = 1,courseName = "history"},
                new Course{stId = 3, courseName = "history"},
                new Course{stId = 3,courseName = "physics"},
            };
    
            static void Main(string[] args)
            {    
               //查询所有选修了history课的学生名
                var query = from s in students
                            join c in courses on s.stId equals c.stId
                            where c.courseName == "history"
                            select s.stuName;
    
                foreach(string str in query)
                {
                    Console.Write("{0}  ", str);
                }
                Console.ReadKey();
            }
        }
    }
    复制代码

    输出 jack fleming

    讲解一下查询过程:它会依次使用student中的对象与course中的所有对象进行对比,查找是否符合 s.stId equals c.stId  where c.courseName == "history" 要求。

    stID stuName
    1 jack
    2 taylor
    3 fleming
     stID  courseName
     1  art
     2  art
     1  history
     3  history
     3  physics

      

     即先将(1,jack)和(1,art),(2,art)...(3,physics)分别匹配,然后再(2,taylor)和(1,art),(2,art)...(3,physics),直到所有都匹配完,最终可以找到两条可以匹配的结果

      2.3    let子句

        let子句接受一个表达式的运算并且把它赋值给一个需要在其他运算中使用的标识符,它是from...let...where片段中的一部分

    var query = from a in groupA
                from b in groupB
                let sum = a + b
                where sum < 12
                select new(a,b,sum);

      2.4 where子句

        where子句根据之后的运算来除去不符合要求的项,一个查询表达式可以有任意多个where子句,一个项必须满足所有的where条件才能避免被过滤,其语法为

    where BoolenExpression1
    where BoolenExpression2

        前面的例子已经多次用过where,这里就不举例了

      2.5  orderby子句

        orderby可以很方便的将返回的数据进行排序,可选ascending和descending两种方式,默认的是ascending

        语法: orderby Expression ascending or descending    二选一

        为join子句中的例子增加一个orderby子句,返回结果就变成了 fleming  jack

    var query = from s in students
                            join c in courses on s.stId equals c.stId
                            where c.courseName == "history"
                   orderby s.stuName  //排序
                            select s.stuName;   

      2.6   group子句

        group子句可以让你把select的结果按指定的键(key)进行分组 ,每一个分组由一个叫做键的字段区分,分组本身是可枚举类型的并且可以枚举它的项

    复制代码
    var query = from student in students
                group student by student.major;
    
                foreach (var s in query)
                {
                    Console.WriteLine("{0}", s.key);
                    foreach (var t in s)
                    {
                        console.writeLine("    {0}", t.Name);
                    }
                }
    复制代码

      2.7 select子句

        select子句指定所选定的对象哪部分应该被选择。可以指定下面的任意一项

          a: 整个数据项

          b: 数据项的一个字段

          c: 数据项中几个字段组成的新对象(或类似其他值)

    复制代码
    var query = from s in students
                            select s;    //整个数据项
    
                var query = from s in students
                            select s.stuName;    //s中的一个字段
    
                var query = from a in groupA
                            from b in groupB
                            let sum = a + b
                            where sum < 12
                            select new (a, b, sum);        //a,b,sum组成的新字段
    复制代码

      2.8  查询延续: into子句

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

    var someInt = from a in groupA
                  from b in groupB
                  into groupAandB
                  from c in groupAandB
                  select c;

    三、方法语法和查询语法

      在使用LINQ写查询时可以使用两种形式的语法:查询语法和方法语法

      a:方法语法(method syntax) : 使用标准的方法调用,这些方法是一组叫做标准查询运算符的方法

      b:查询语法(query method)  : 看上去和SQL语句很相似,使用查询表达式形式书写。微软推荐使用查询语法,因为它更易读

      在编译时,CLR会将查询语法转换为方法语法

    复制代码
     int[] num = { 2, 4, 6, 8, 10 };
    
     var numQuery = from number in num   //查询语法
                    where number < 8
                    select number;
    
     var numMethod = num.Where(x => x < 8);  //方法语法
    复制代码

    它们得到的结果是一样的。方法语法中where的参数使用了Lambda表达式

  • 相关阅读:
    1、SASS / SCSS 总结简介
    Chrome 中的 JavaScript 断点设置和调试技巧
    《Javascript 设计模式》-读书笔记
    CSS基线之道
    高性能 CSS3 动画
    《编写高质量代码》web前端开发修炼之道-读书笔记
    《Effective JavaScript》编写高质量的Javascript代码的68个有效方法-读书笔记
    Sea.js-模块化开发框架
    JSLine和JSHint代码质量检查工具和uglifyjs压缩JS的
    在Windows平台上安装Node.js及NPM模块管理
  • 原文地址:https://www.cnblogs.com/summer2008/p/13730041.html
Copyright © 2020-2023  润新知