Linq(語言集成查詢)_第1頁
Linq(語言集成查詢)_第2頁
Linq(語言集成查詢)_第3頁
Linq(語言集成查詢)_第4頁
Linq(語言集成查詢)_第5頁
已閱讀5頁,還剩56頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、Linq(語言集成查詢),主講人:大牛,本章目標(biāo),掌握 LINQ 中的基本概念 掌握 LINQ 的組成 掌握 Linq查詢關(guān)鍵字 from where select group into orderby join let equals 掌握基本查詢方法 Select() Where() OrderBy() GroupBy(),LINQ要解決的問題,長(zhǎng)期以來,開發(fā)社區(qū)形成以下格局: 面向?qū)ο笈c數(shù)據(jù)訪問兩個(gè)領(lǐng)域長(zhǎng)期分裂,各自為政 編程語言中的數(shù)據(jù)類型與數(shù)據(jù)庫中的數(shù)據(jù)類型形成兩套體系。例如: C# 中字符串用 string 表示 SQL 中字符串用 NVarchar/Varchar/Char 表示

2、SQL 編碼體驗(yàn)落后 沒有智能感應(yīng) 沒有嚴(yán)格意義上的強(qiáng)類型和類型檢查 SQL 和 XML 都有各自的查詢語言,而對(duì)象沒有自己的查詢語言,LINQ 將改變這一切!,LINQ 的歷史,最初由 Anders Hejlsberg 構(gòu)思,最初的研究計(jì)劃稱為 C 2005年9月 第一個(gè)為 C# 2.0 開發(fā)的技術(shù)預(yù)覽版在當(dāng)年的 PDC(微軟開發(fā)者大會(huì))上發(fā)布 2005年11月 更新至社區(qū)預(yù)覽版(C# 2.0) 2006年1月 第一個(gè)為 VB 8.0 開發(fā)的技術(shù)預(yù)覽版發(fā)布 2007年11月19日 LINQ作為 .NET Framework 3.5 的一部分正式發(fā)布,Anders Hejlsberg,LINQ

3、是什么,LINQ( Language Integrated Query )即語言集成查詢 LINQ 是一組語言特性和API,使得你可以使用統(tǒng)一的方式編寫各種查詢。查詢的對(duì)象包括XML、對(duì)象集合、SQL Server 數(shù)據(jù)庫等等。 LINQ 主要包含以下三部分: LINQ to Objects 主要負(fù)責(zé)對(duì)象的查詢(如:集合、數(shù)組、字符串等) LINQ to XML 主要負(fù)責(zé) XML 的查詢 LINQ to ADO.NET 主要負(fù)責(zé)數(shù)據(jù)庫的查詢 LINQ to SQL LINQ to DataSet LINQ to Entities,LINQ 的組成,LNIQ to Objects,LINQ to

4、 ADO.NET,LINQ to XML,C#,VB,Others,LINQ 初體驗(yàn),在沒有LINQ以前,我們這樣查詢:,int numbers = new int 6, 4, 3, 2, 9, 1, 7, 8, 5 ; List even = new List(); foreach (int number in numbers) if (number % 2 = 0) even.Add(number); even.Sort(); even.Reverse();,從 numbers 數(shù)組中提取偶數(shù)并降序排列,LINQ 初體驗(yàn),今天,我們有了LINQ! 我們這樣查詢:,int numbers =

5、 new int 6, 4, 3, 2, 9, 1, 7, 8, 5 ; var even = numbers .Where(p = p % 2 = 0) .Select(p = p) .OrderByDescending(p = p);,從 numbers 數(shù)組中提取偶數(shù)并降序排列,演示示例:Hello, LINQ,from 子句,查詢表達(dá)式必須以 from 子句開頭。另外,查詢表達(dá)式還可以包含子查詢,子查詢也是以 from 子句開頭。 from 子句指定以下內(nèi)容 將對(duì)其運(yùn)行查詢或子查詢的數(shù)據(jù)源。 一個(gè)本地范圍變量,表示源序列中的每個(gè)元素。,int numbers = 5, 4, 1, 3,

6、 9, 8, 6, 7, 2, 0 ; var lowNums = from num in numbers where num 5 select num; foreach (int i in lowNums) Console.Write(i + ); 輸出結(jié)果: 4 1 3 2 0,范圍變量,where 子句,where 子句用在查詢表達(dá)式中,用于指定將在查詢表達(dá)式中返回?cái)?shù)據(jù)源中的哪些元素。一個(gè)查詢表達(dá)式可以包含多個(gè) where 子句,一個(gè)子句可以包含多個(gè)謂詞子表達(dá)式。,int numbers = 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 ; var queryLowNums

7、= from num in numbers where num 5 select num; foreach (var s in queryLowNums) Console.Write(s.ToString() + ); 輸出結(jié)果: 4 1 3 2 0,謂詞(布爾條件 ),select 子句,在查詢表達(dá)式中,select 子句可以指定將在執(zhí)行查詢時(shí)產(chǎn)生的值的類型。該子句的結(jié)果將基于前面所有子句的計(jì)算結(jié)果以及 select 子句本身中的所有表達(dá)式。查詢表達(dá)式必須以 select 子句或 group 子句結(jié)束。,List Scores = new List() 97, 92, 81, 60 ; IE

8、numerable queryHighScores = from score in Scores where score 80 select score; foreach (int i in queryHighScores) Console.Write(i + ); 輸出結(jié)果: 97 92 81,group 子句,group 子句返回一個(gè) IGrouping) 對(duì)象序列,這些對(duì)象包含零個(gè)或更多個(gè)與該組的鍵值匹配的項(xiàng)。,var studentQuery2 = from student in students group student by student.Last0 into g orderb

9、y g.Key select g;,in,in 上下文關(guān)鍵字可在下面兩種上下文中使用: foreach 語句 查詢表達(dá)式中的 join 子句,by,by 上下文關(guān)鍵字用在查詢表達(dá)式的 group 子句中,用于指定如何對(duì)返回的項(xiàng)進(jìn)行分組。,var query = from student in students group student by student.LastName0;,equals,equals 上下文關(guān)鍵字用在查詢表達(dá)式的 join 子句中,用于比較兩個(gè)序列的元素。,var innerJoinQuery = from category in categories join pro

10、d in products on category.ID equals prod.CategoryID select new ProductName = prod.Name, Category = category.Name ;,on,on 上下文關(guān)鍵字在查詢表達(dá)式的 join 子句中用于指定聯(lián)接條件。,var innerJoinQuery = from category in categories join prod in products on category.ID equals prod.CategoryID select new ProductName = prod.Name, Ca

11、tegory = category.Name ;,descending,descending 上下文關(guān)鍵字用在查詢表達(dá)式的 orderby 子句中,用于指定從最大到最小的排序順序。,ascending,ascending 上下文關(guān)鍵字用在查詢表達(dá)式的 orderby 子句中,用于指定從最小到最大的排序順序。因?yàn)?ascending 是默認(rèn)排序順序,所以您無須指定它。,let 子句,基本查詢操作符-獲取數(shù)據(jù),public static IEnumerable Select ( this IEnumerable source, Func selector ),Select(),說明 Select

12、方法本身是一個(gè)泛型擴(kuò)展方法 它作用于IEnumerable類型 它只接受一個(gè) Func 類型參數(shù) Func 是一個(gè)泛型委托,位于System名字空間下,System.Core.dll中 在這里 selector 是一個(gè)提取器,Select() 例子,var q1 = foxRiver8.Select (name = name.ToLower(); foreach (var item in q1) Console.WriteLine(item); ,以 Lambda 表達(dá)式形式出現(xiàn)的Func委托實(shí)例,演示示例:Select方法示例,基本查詢操作符-過濾數(shù)據(jù),public static IEnum

13、erable Where( this IEnumerable source, Func predicate ),Where(),說明 Where方法也是一個(gè)泛型擴(kuò)展方法 它和 Select() 一樣作用于IEnumerable類型 它只接受一個(gè) Func 泛型委托參數(shù) 在這里 predicate 是一個(gè)判斷條件,Where() 例子,var q2 = foxRiver8 .Where( name = name.StartsWith(T) .Select(name = name.ToLower(); foreach (var item in q2) Console.WriteLine(item)

14、; ,以 Lambda 表達(dá)式形式出現(xiàn)的判斷條件,注意返回值要求為 bool 類型,演示示例:Where方法示例,基本查詢操作符-排序數(shù)據(jù),public static IOrderedEnumerable OrderBy( this IEnumerable source, Func keySelector ),OrderBy(),說明 OrderBy方法也是一個(gè)泛型擴(kuò)展方法 它和 Select() 一樣作用于IEnumerable類型 它只接受一個(gè) Func 類型參數(shù) 在這里 keySelector 指定要排序的字段 如果想降序排列可以使用OrderByDescending方法,OrderBy

15、() 例子,var q3 = foxRiver8 .Where(name = name.Length 5) .Select(name = name.ToLower() .OrderBy(name = name.Substring(1,1) foreach (var item in q3) Console.WriteLine(item); ,排序字段,這里指定按照姓名的第二個(gè)字母升序排列,演示示例:OrderBy方法示例,基本查詢操作符-分組數(shù)據(jù),public static IEnumerable GroupBy( this IEnumerable source, Func keySelecto

16、r ),GroupBy(),說明 GroupBy方法和OrderBy方法非常類似,它也是一個(gè)泛型擴(kuò)展方法 它和 OrderBy() 一樣作用于IEnumerable類型 它只接受一個(gè) Func 類型參數(shù) 在這里 keySelector 指定要分組的字段,請(qǐng)注意這個(gè)返回值與前面方法的返回值的區(qū)別,GroupBy() 例子,var q4 = foxRiver8 .Where(name = name.Length 5) .Select(name = name.ToLower() .GroupBy(name = name.Substring(0, 1); foreach (var group in q

17、4) Console.WriteLine(group.Key); Console.WriteLine(-); foreach (var item in group) Console.WriteLine(item); ,外層循環(huán)得到分組,演示示例:GroupBy方法示例,內(nèi)層循環(huán)得到分組中的項(xiàng),查詢執(zhí)行的時(shí)機(jī),int numbers = new int 6, 4, 3, 2, 9, 1, 7, 8, 5 ; var even = numbers .Where(p = p % 2 = 0) .Select(p = Console.WriteLine(Hi! + p.ToString(); retu

18、rn p; );,演示示例:查詢的時(shí)機(jī),請(qǐng)判斷以下代碼輸出結(jié)果是什么?,查詢執(zhí)行的時(shí)機(jī),var even = numbers .Where(p = p % 2 = 0) .Select(p = Console.WriteLine(Hi! + p.ToString(); return p; );,int numbers = new int 6, 4, 3, 2, 9, 1, 7, 8, 5 ;,定義查詢,獲取數(shù)據(jù)源,執(zhí)行查詢,foreach (var item in even) ,從前面的試驗(yàn)中,我們發(fā)現(xiàn)一次查詢實(shí)際經(jīng)過以下三步,1,2,3,查詢執(zhí)行的時(shí)機(jī)小結(jié),查詢分為以下三步:獲取數(shù)據(jù)源、定義

19、查詢、執(zhí)行查詢; 定義查詢后,查詢直到需要枚舉結(jié)果時(shí)才被真正執(zhí)行,這種方式稱為“延遲執(zhí)行(deferred execution)”; 當(dāng)查詢方法返回單一值時(shí),查詢立即執(zhí)行; 因此,可以通過以下技巧在定義查詢時(shí)就強(qiáng)制執(zhí)行查詢;,var even = numbers .Where(p = p % 2 = 0) .Select(p = Console.WriteLine(Hi! + p.ToString(); return p; ).Count();,LINQ查詢的兩種方式,事實(shí)上,LINQ查詢存在以下兩種形式 Method Syntax, 查詢方法方式 主要利用 System.Linq.Enume

20、rable 類中定義的擴(kuò)展方法和 Lambda 表達(dá)式方式進(jìn)行查詢 上一章的例子都是以這種方式查詢 Query Syntax, 查詢語句方式 一種更接近 SQL 語法的查詢方式 可讀性更好,查詢語句,int numbers = new int 6, 4, 3, 2, 9, 1, 7, 8, 5 ; var even = numbers .Where(p = p % 2 = 0) .OrderByDescending(p = p) .Select(p = p);,int numbers = new int 6, 4, 3, 2, 9, 1, 7, 8, 5 ; var even = from n

21、umber in numbers where number % 2 = 0 orderby number descending select number;,查詢方法,查詢語句,演示示例:查詢語句與查詢方法對(duì)比示例,兩者的執(zhí)行效果完全一樣,更復(fù)雜的查詢語句示例,List foxRiver8 = GetFoxRiver8(); var q = from p in foxRiver8 where p.Age = 30 ,演示示例:復(fù)雜的查詢語句示例,請(qǐng)判斷以下代碼輸出結(jié)果是什么?,查詢語句vs查詢方法,查詢語句與查詢方法存在著緊密的關(guān)系 CLR本身并不理解查詢語句,它只理解查詢方法 編譯器負(fù)責(zé)在編

22、譯時(shí)將查詢語句翻譯為查詢方法 大部分查詢方法都有對(duì)應(yīng)的查詢語句形式:如 Select() 對(duì)應(yīng) select 、 OrderBy() 對(duì)應(yīng) orderby 部分查詢方法目前在C#中還沒有對(duì)應(yīng)的查詢語句:如 Count()和Max() 這時(shí)只能采用以下替代方案 查詢方法 查詢語句 + 查詢方法的混合方式; 一般情況下,建議使用可讀性更好的查詢語句,高級(jí)查詢方法,高級(jí)查詢方法 聚合類 Count,Max/Min,Average 排序類 ThenBy 分區(qū)類 Take,TakeWhile,Skip,SkipWhile 集合類 Distinct 生成類 Range, Repeat,聚合類查詢方法,聚合

23、類查詢方法,Count Max/Min Average,Count 示例,int count = foxRiver8 .Where(p = p.Age = 30) .Count();,int count = (from p in foxRiver8 where p.Age = 30 select p).Count();,純粹查詢方法模式,混合模式,演示示例:Count 方法示例,Count 返回集合項(xiàng)的數(shù)目,Max 示例,int maxAge = foxRiver8 .Select(p = p.Age) .Max();,int maxAge = (from p in foxRiver8 sel

24、ect p.Age).Max();,純粹查詢方法模式,混合模式,演示示例:Max 方法示例,Max 返回集合中的最大值,Min 示例,int maxAge = foxRiver8 .Select(p = p.Age) .Min();,int maxAge = (from p in foxRiver8 select p.Age).Min();,純粹查詢方法模式,混合模式,演示示例:Min 方法示例,Min 返回集合中的最小值,Average 示例,double averageAge = foxRiver8 .Select(p = p.Age) .Average();,double average

25、Age = (from p in foxRiver8 select p.Age).Average();,純粹查詢方法模式,混合模式,演示示例:Average 方法示例,Average 返回集合的平均值,Sum 示例,int sumAge = foxRiver8 .Select(p = p.Age) .Sum();,Int sumAge = (from p in foxRiver8 select p.Age).Sum();,純粹查詢方法模式,混合模式,演示示例:Sum 方法示例,Sum 返回集合的總和,排序類查詢方法,排序類查詢方法,ThenBy,ThenBy 示例,var q = from p

26、 in foxRiver8 orderby p.FirstName, p.LasName, p.Age select p;,var q = foxRiver8 .OrderBy(p = p.FirstName) .ThenBy(p = p.LasName) .ThenBy(p = p.Age);,查詢語句,查詢方法,演示示例:ThenBy 方法示例,ThenBy 提供復(fù)合排序條件,分區(qū)類查詢方法,分區(qū)類查詢方法,Take/TakeWhile Skip/SkipWhile,Take/Skip 示例,int numbers = 1, 2, 3, 4, 5, 6, 7, 8, 9 ; var q =

27、 numbers.Skip(1).Take(3); foreach (var item in q) Console.WriteLine(item); ,演示示例:Skip/Take 方法示例,Take 提取指定數(shù)量的項(xiàng) Skip 跳過指定數(shù)量的項(xiàng)并獲取剩余的項(xiàng),跳過前1條記錄,連續(xù)提取3條記錄,得到 2 3 4,TakeWhile/SkipWhile 示例,演示示例:SkipWhile/TakeWhile 方法示例,TakeWhile 根據(jù)指定條件提取項(xiàng) SkipWhile 根據(jù)指定條件跳過項(xiàng),int numbers = 1, 2, 3, 4, 5, 6, 7, 8, 9 ; var q =

28、numbers.SkipWhile(i = i % 3 != 0) .TakeWhile(i = i % 2 != 0); foreach (var item in q) Console.WriteLine(item); ,分區(qū)類查詢方法小結(jié),請(qǐng)判斷以下代碼輸出結(jié)果是什么?,int numbers = 1, 2, 3, 4, 5, 6, 7, 8, 9 ; var q = numbers.Skip(1).Take(3).Skip(1).Take(2); foreach (var item in q) Console.WriteLine(item); ,輸出: 3 4,集合類查詢方法,集合類查詢

29、方法,Distinct,Distinct 示例,演示示例:Distinct 方法示例,Distinct 去掉集合中的重復(fù)項(xiàng),int factorsOf300 = 2, 2, 3, 5, 5 ; var uniqueFactors = factorsOf300.Distinct();,輸出: 2 3 5,生成類查詢方法,生成類查詢方法,Range Repeat,Range 示例,演示示例:Range 方法示例,Range 生成一個(gè)整數(shù)序列,var numbers =Enumerable.Range(1, 10); foreach (var item in numbers) Console.Wri

30、teLine(item); ,Repeat 示例,演示示例:Repeat 方法示例,Repeat 生成一個(gè)重復(fù)項(xiàng)的序列,var numbers = Enumerable.Repeat(“Beijing 2008”, 10); foreach (var item in numbers) Console.WriteLine(item); ,生成類查詢方法小結(jié),使用生成類查詢方法時(shí),需要注意以下幾點(diǎn): 和其他幾類方法不同,Range/Repeat 不是擴(kuò)展方法,而是普通的靜態(tài)方法 Range 只能產(chǎn)生整數(shù)序列 Repeat 可以產(chǎn)生泛型序列 所有的查詢方法都存放在 System.Linq.Enume

31、rable 靜態(tài)類中,LINQ to SQL 示例,下面我們利用已經(jīng)學(xué)習(xí)的 LINQ 知識(shí),做一個(gè)示例 顯示“第三波書店”中所有書籍類型 根據(jù)用戶選擇的書籍類型顯示書籍列表 提供分頁功能: 首頁 上一頁 下一頁 末頁 頁碼選擇,設(shè)計(jì)界面,關(guān)鍵步驟 新建 “ASP.NET Web Site” 項(xiàng)目 在 “Solution Explorer” 中依次選擇 “Add New Item” - “Web Form” 為網(wǎng)頁命名為 ListBooksByCategory.aspx 設(shè)計(jì)簡(jiǎn)單的用戶界面,設(shè)計(jì)好后的界面如圖所示,配置數(shù)據(jù)源,關(guān)鍵步驟 在 “Database Explorer” 中選擇 “Add

32、 Connection”,并指定 MyBookShop 數(shù)據(jù)庫 在 “Solution Explorer” 中依次選擇 “Add New Item” - “LINQ to SQL Classes” 為dbml文件命名為 MyBookShop.dbml 展開數(shù)據(jù)源視圖,把 MyBookShop 數(shù)據(jù)庫中的表 Books, Categories, Publishers 拖到 LINQ to SQL 的設(shè)計(jì)器中 最終效果如圖,編寫代碼,在 Page_Load 中編寫代碼進(jìn)行初始化,private const int PAGE_SIZE = 20; MyBookShopDataContext db; protected void Page_Load(object sender, EventArgs e) db = new MyBookShopDat

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論