一、LINQ简介

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

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

using System;
using System.Collections.Generic;
using System.Linq;

namespace LINK查询
{
 class Program
 {
 static void Main(string[] args)
 {
  int[] number = { 1, 100, 22, 4, 6, 8, 10 };     //获取数据源
  IEnumerable<int> lowNum = from n in number       //创建并存储查询,不会执行操作
     where n < 10
     select n;

  foreach(var val in lowNum) //执行查询
  {
      Console.Write("{0} ", val);
  }

  Console.ReadKey();
 }
 }
}

方法语法和查询语法

int[] num = { 1, 2, 4, 6, 8, 10, 200 };

var numQuery = from number in num //查询语法
    where number < 10
    select number;

var numMethod = num.Where(x => x < 10); //方法语法

一般情况为了代码的易读性,我们通常使用方法语法

二、查询表达式的结构

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

2.1.from子句

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

from Type Item in Items

其中Type是集合中元素的类型,是可选的,因为编译器可以从集合来推断类型。Item是迭代变量的名字。Items是要查询的集合的名字,必须是可枚举类型的,它和foreach比较相似,但foreach语句在遇到代码时就执行其主体,from子句什么也不执行。它创建可以执行的后台代码对象,只有在程序的访问查询变量语句时才会执行

2.2.join子句

和SQL中的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 LinkTest
{
    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 = "guo"},
          new Student {stId = 2,stuName = "zhang"},
          new Student {stId = 3,stuName = "wang"}
        };

        static Course[] courses = new Course[]
        {
          new Course{stId = 1, courseName = "art"},
          new Course{stId = 2, courseName = "art"},
          new Course{stId = 1, courseName = "music"},
          new Course{stId = 3, courseName = "history"},
          new Course{stId = 3, courseName = "physics"},
        };

        static void Main(string[] args)
        {
            //查询所有选music课的学生名
            var query = from s in students
                        join c in courses on s.stId equals c.stId
                        where c.courseName == "music"
                        select s.stuName;

            foreach (string str in query)
            {
                Console.Write("{0} ", str);
            }

            Console.ReadKey();
        }
    }
}

2.3.where子句

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

where(p => name == name)
where BoolenExpression
var queryTwo = courses.Where(p => p.courseName == "music");

2.4.orderby子句

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

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

var queryTwo = courses.OrderBy(p => p.courseName);

2.5.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.6.查询延续into子句

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

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

方法语法中where的参数使用了Lambda表达式