為什么要學習Linq?
在我們日常開發中,經常需要從數據庫中執行各式各樣的查詢來獲取需要的數據。但是如果需要對查詢獲得的數據進行二次篩選呢?linq就提供了對於可枚舉類型(實現IEnumerable接口)的一種便捷查詢方式。正如其名Language Integrated Query語言集成查詢。
下載LinqPad
LinqPad官方網站http://www.linqpad.net/,此篇示例使用的是LinqPad4。
安裝完成后界面如下:
點擊左側Add connection,添加數據庫連接,本機是sqlserver 2008 R2,選擇默認的LINQ to SQL,NEXT,選擇你想要添加的數據庫,點擊OK即可添加成功。
展開你連接的庫樹,表,存儲過程,方法等都能夠在視圖中展示(如果數據庫存在架構,表存放在其所屬架構下)。
所有的表展開后都成為了”表名s”的格式,體現了Linq查詢將表當做數據的集合的思想。
Linq的語法
右鍵選中其中一個集合彈出菜單。
分割線上:Take/Count/Where均是Qureyable方法(查詢方法),以及兩個查詢模板。
分割線下:查詢或編輯數據。
這里我們選擇第一個模板
代碼編輯窗口出現如下代碼,這是一個比較直觀的Linq語句模板
from p in Persons where p. select p
Language→C# Program 並將其補充完整為我們在.Net開發中經常用到的C#代碼塊格式。
void Main() { var result = from p in Persons where p.MiddleName == "A" select p; result.Count().Dump();//輸出結果個數 }
以此為基礎,可以對Linq語句進行擴展
- 所有的linq查詢都是以from開始,select或group結束。
- p是范圍變量,Persons是數據集合。
- where關鍵字后是查詢條件,可以同時存在多個where
補充:有時編譯器不能夠識別自定義類型,可以顯式指定范圍變量的類型。如:from Person p in Persons。
where p.MiddleName=="A" where p.Title=="Mr." //等同於 where p.MiddleName=="A"&&where p.Title=="Mr."
指得注意的是,var是推斷類型,C#3.0新出的特性。編譯器編譯的過程中推斷變量是什么類型,和所謂的強弱類型無關。(很多人說var是弱類型,這個是錯誤的)。
比如,下圖編譯器推斷dr為Object類型,無法通過索引器去訪問,編譯時報錯。
更改為DataRow后編譯通過
PS: 既然是在編譯過程中推斷而不是運行時,所以就沒有效率高低之分。但是為了代碼的易讀性和鞏固基礎,少用為好。
排序orderby:
var result=from p in Persons where p.MiddleName=="A" orderby p.EmailPromotion //默認升序,降序descending select p;
分組group by:
var result=from p in Persons where p.MiddleName=="A" group p by p.Title;
let關鍵字:在查詢中定義變量。
into關鍵字:將查詢結果放入一個變量,再次使用。
var result=from p in Persons let midname=p.MiddleName where midname=="A"|| midname=="J" group p by p.Title into temp where temp.Count()>1 select temp;
join關鍵字:內連接,左連接,右連接。此處用到了linq to sql
void KeyWordJoin() { DataContext ctx = new DataContext(); //內連接 var innerJoin = from p in ctx.Person where p.BusinessEntityID == 9 join c in ctx.Customer on p.BusinessEntityID equals c.CustomerID select p; //左連接 var leftJoin = from p in ctx.Person join c in ctx.Customer on p.BusinessEntityID equals c.CustomerID into joined from j in joined.DefaultIfEmpty() //join操作后,返回的集合為在后方的類型此處為Customer select new { ID = p.BusinessEntityID, Number = j == null ? null : j.AccountNumber }; //右連接同理 var rightJoin = from c in ctx.Customer join p in ctx.Person on c.CustomerID equals p.BusinessEntityID into joined from j in joined.DefaultIfEmpty() select new { ID = c.CustomerID, Last = j == null ? null : j.LastName}; }