一、什么是LINQ
LINQ(讀音link)代表語言集成查詢(Language Integrated Query),是.NEt框架的擴(kuò)展,它允許我們用SQL查詢數(shù)據(jù)庫的方式來查詢數(shù)據(jù)的集合,使用它,你可以從數(shù)據(jù)庫、程序?qū)ο蟮募弦约癤ML文檔中查詢數(shù)據(jù)
下面一個(gè)簡單的示例,可以查詢數(shù)組中小于8的數(shù)字并輸出。
一般步驟:獲取數(shù)據(jù)源、創(chuàng)建查詢、執(zhí)行查詢。需要注意的是,盡管查詢在語句中定義,但直到最后的foreach語句請求其結(jié)果的時(shí)候才會(huì)執(zhí)行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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 }; //獲取數(shù)據(jù)源 IEnumerable< int > lowNum = from n in number //創(chuàng)建并存儲(chǔ)查詢,不會(huì)執(zhí)行操作 where n < 8 select n; foreach (var val in lowNum) //執(zhí)行查詢 { Console.Write( "{0} " , val); } Console.ReadKey(); } } } |
二、查詢表達(dá)式的結(jié)構(gòu)
查詢表達(dá)式由查詢體后的from子句組成,其子句必須按一定的順序出現(xiàn),并且from子句和select子句這兩部分是必須的。先介紹一下子句
2.1 from子句
from子句指定了要作為數(shù)據(jù)源使用的數(shù)據(jù)集合,它的語法是:
1
|
from Type Item in Items |
其中Type是集合中元素的類型,是可選的,因?yàn)榫幾g器可以從集合來推斷類型?! tem是迭代變量的名字。 Items是要查詢的集合的名字,必須是可枚舉類型的
它和foreach比較相似,但foreach語句在遇到代碼時(shí)就執(zhí)行其主體,二from子句什么也不執(zhí)行。它創(chuàng)建可以執(zhí)行的后臺代碼對象,只有在程序的控制流遇到訪問查詢變量的語句時(shí)才會(huì)執(zhí)行
2.2 join子句
如果您對SQL中的join比較熟悉的話,那么LINQ中的join對你來說也不是什么難事,不熟悉的話,,當(dāng)我沒說。
我們可以使用join來結(jié)合兩個(gè)或更多集合中的數(shù)據(jù),它接受兩個(gè)集合然后創(chuàng)建一個(gè)臨時(shí)的對象集合
1
2
|
var query = from s in students join c in course on s.SID equals c.SID |
equals用于比較相等性的字段,不能使用“==”代替,下面示例中有三個(gè)學(xué)生和三門課程,我們要做的是查找選修了歷史課的學(xué)生名
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 //聲明student類 { public int stId; //學(xué)生ID public string stuName; //學(xué)生姓名 } public class Course //聲明course類 { public int stId; //學(xué)生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課的學(xué)生名 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
講解一下查詢過程:它會(huì)依次使用student中的對象與course中的所有對象進(jìn)行對比,查找是否符合 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),直到所有都匹配完,最終可以找到兩條可以匹配的結(jié)果
2.3 let子句
let子句接受一個(gè)表達(dá)式的運(yùn)算并且把它賦值給一個(gè)需要在其他運(yùn)算中使用的標(biāo)識符,它是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); |
2.4 where子句
where子句根據(jù)之后的運(yùn)算來除去不符合要求的項(xiàng),一個(gè)查詢表達(dá)式可以有任意多個(gè)where子句,一個(gè)項(xiàng)必須滿足所有的where條件才能避免被過濾,其語法為
1
2
|
where BoolenExpression1 where BoolenExpression2 |
前面的例子已經(jīng)多次用過where,這里就不舉例了
2.5 orderby子句
orderby可以很方便的將返回的數(shù)據(jù)進(jìn)行排序,可選ascending和descending兩種方式,默認(rèn)的是ascending
語法: orderby Expression ascending or descending 二選一
為join子句中的例子增加一個(gè)orderby子句,返回結(jié)果就變成了 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; |
2.6 group子句
group子句可以讓你把select的結(jié)果按指定的鍵(key)進(jìn)行分組 ,每一個(gè)分組由一個(gè)叫做鍵的字段區(qū)分,分組本身是可枚舉類型的并且可以枚舉它的項(xiàng)
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); } } |
2.7 select子句
select子句指定所選定的對象哪部分應(yīng)該被選擇??梢灾付ㄏ旅娴娜我庖豁?xiàng)
a: 整個(gè)數(shù)據(jù)項(xiàng)
b: 數(shù)據(jù)項(xiàng)的一個(gè)字段
c: 數(shù)據(jù)項(xiàng)中幾個(gè)字段組成的新對象(或類似其他值)
1
2
3
4
5
6
7
8
9
10
11
|
var query = from s in students select s; //整個(gè)數(shù)據(jù)項(xiàng) var query = from s in students select s.stuName; //s中的一個(gè)字段 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 查詢延續(xù): into子句
查詢延續(xù)子句可以接受查詢的一部分結(jié)構(gòu)并賦予一個(gè)名字,從而可以在查詢的另一部分中使用
1
2
3
4
5
|
var someInt = from a in groupA from b in groupB into groupAandB from c in groupAandB select c; |
三、方法語法和查詢語法
在使用LINQ寫查詢時(shí)可以使用兩種形式的語法:查詢語法和方法語法
a:方法語法(method syntax) : 使用標(biāo)準(zhǔn)的方法調(diào)用,這些方法是一組叫做標(biāo)準(zhǔn)查詢運(yùn)算符的方法
b:查詢語法(query method) : 看上去和SQL語句很相似,使用查詢表達(dá)式形式書寫。微軟推薦使用查詢語法,因?yàn)樗鬃x
在編譯時(shí),CLR會(huì)將查詢語法轉(zhuǎn)換為方法語法
1
2
3
4
5
6
7
|
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); //方法語法 |
它們得到的結(jié)果是一樣的。方法語法中where的參數(shù)使用了Lambda表達(dá)式
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對服務(wù)器之家的支持。
原文鏈接:https://www.cnblogs.com/forever-Ys/p/10322130.html