LINQ(读音link)代表语言集成查询(Language Integrated Query),是.NEt框架的扩展,它允许我们用SQL查询数据库的方式来查询数据的集合,使用它,你可以从数据库、程序对象的集合以及XML文档中查询数据
Linq语法
let子句 |
let子句接受一个表达式的运算并且把它赋值给一个需要在其他运算中使用的标识符,它是from...let...where片段中的一部分
?
1
2
3
4
5
|
var query = from a in groupA
from b in groupB
let sum = a + b
where sum < 12
select new (a,b,sum);
|
|
from子句 |
from子句指定了要作为数据源使用的数据集合,它的语法是:
?
1
|
from Type Item in Items
|
其中Type是集合中元素的类型,是可选的,因为编译器可以从集合来推断类型。 Item是迭代变量的名字。 Items是要查询的集合的名字,必须是可枚举类型的
它和foreach比较相似,但foreach语句在遇到代码时就执行其主体,二from子句什么也不执行。它创建可以执行的后台代码对象,只有在程序的控制流遇到访问查询变量的语句时才会执行
|
join子句 |
如果您对SQL中的join比较熟悉的话,那么LINQ中的join对你来说也不是什么难事,不熟悉的话,,当我没说。
我们可以使用join来结合两个或更多集合中的数据,它接受两个集合然后创建一个临时的对象集合
?
1
2
|
var query = from s in students
join c in course on s.SID equals c.SID
|
equals用于比较相等性的字段,不能使用“==”代替,下面示例中有三个学生和三门课程,我们要做的是查找选修了历史课的学生名
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LINK查询
{
class Program
{
public class Student
{
public int stId;
public string stuName;
}
public class Course
{
public int stId;
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)
{
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),直到所有都匹配完,最终可以找到两条可以匹配的结果
|
where子句 |
where子句根据之后的运算来除去不符合要求的项,一个查询表达式可以有任意多个where子句,一个项必须满足所有的where条件才能避免被过滤,其语法为
?
1
2
|
where BoolenExpression1
where BoolenExpression2
|
前面的例子已经多次用过where,这里就不举例了
|
orderby子句 |
orderby可以很方便的将返回的数据进行排序,可选ascending和descending两种方式,默认的是ascending
语法: orderby Expression ascending or descending 二选一
为join子句中的例子增加一个orderby子句,返回结果就变成了 fleming jack
?
1
2
3
4
5
|
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;
|
|
group子句 |
group子句可以让你把select的结果按指定的键(key)进行分组 ,每一个分组由一个叫做键的字段区分,分组本身是可枚举类型的并且可以枚举它的项
?
1
2
3
4
5
6
7
8
9
10
11
|
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);
}
}
|
|
select子句 |
select子句指定所选定的对象哪部分应该被选择。可以指定下面的任意一项
a: 整个数据项
b: 数据项的一个字段
c: 数据项中几个字段组成的新对象(或类似其他值)
?
1
2
3
4
5
6
7
8
9
10
11
|
var query = from s in students
select s;
var query = from s in students
select s.stuName;
var query = from a in groupA
from b in groupB
let sum = a + b
where sum < 12
select new (a, b, sum);
|
|
查询延续: into子句 |
查询延续子句可以接受查询的一部分结构并赋予一个名字,从而可以在查询的另一部分中使用
?
1
2
3
4
5
|
var someInt = from a in groupA
from b in groupB
into groupAandB
from c in groupAandB
select c;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
end