標籤:
終於看到了第11章,之前雖然也有看過,但沒有太仔細,在工作中也偶爾會使用,但不明白其中的原理,那現在就來講講LINQ,做一做書蟲~~
首先先瞭解下LINQ的三個要點:
- LINQ不能把非常複雜的查詢運算式轉換成一行代碼
- 使用LINQ不意味著你從此不再需要使用SQL
- LINQ不可能魔法般地讓你成為架構天才
序列是LINQ的基礎,在你看到一個查詢運算式的時候,應該要想到它所涉及的序列:一開始總是存在至少一個序列,且通常在中間過程會轉換成其他序列,也可能和其他序列串連在一起。
1 class Car 2 { 3 public string Owner { get; set; } 4 public double Mileage { get; set; } 5 } 6 7 class Program 8 { 9 static void Main(string[] args)10 {11 var list = new List<Car> {12 new Car() { Owner="a",Mileage=100},13 new Car() { Owner="b",Mileage=200},14 new Car() { Owner="c",Mileage=300},15 new Car() { Owner="d",Mileage=400},16 new Car() { Owner="e",Mileage=500},17 new Car() { Owner="f",Mileage=600}18 };19 20 var result = from e in list21 where e.Mileage > 20022 select e;23 24 result.ToList().ForEach(x => Console.WriteLine(x.Owner));25 26 Console.ReadKey();27 28 }29 }
上述的運算式作用:從一個汽車序列中找到裡程大於200的車。下一句代碼使用Lambda運算式來列印篩選出來的車主名。
上述中的查詢運算式被建立的時候,不會立刻處理資料,也不會訪問原始的汽車序列,而是在記憶體中產生這個查詢的表現形式,這個特點叫順延強制。如下,在result.ToList()執行時,才會開始對序列的操作。
select expression 格式的語句,稱為投影。
1 result.Where(e => e.Mileage > 200).Select(e => e);
查詢運算式會編譯器轉譯為上面的代碼,可以看到它們是由擴充方法和Lambda運算式組成。在任何時候,參數(大多情況)都是委託類型,編譯器將用Lambda運算式作為實參,並盡量找到具有合適簽名的方法。再來看下我們的運算式
1 var result = from e in list2 where e.Mileage > 2003 select e;
from、where、in、select為查詢運算式內容關鍵字,e為範圍變數、list為資料來源序列、select e為返回投影。再看一個返回投影的例子。
1 var result1 = from e in list2 where e.Mileage > 2003 select e.Owner;
這裡的select e.Owner,即返回每輛車主的名字,那麼result1的類型為IEnumerable<string>
1 class Bigtruck :Car 2 { 3 public double Volume { get; set; } 4 5 } 6 7 var list0 = new List<Car> { 8 new Car() { Owner="a",Mileage=100}, 9 new Bigtruck() { Owner="b",Mileage=200,Volume=100.1},10 new Bigtruck() { Owner="c",Mileage=300,Volume=100.2},11 new Bigtruck() { Owner="d",Mileage=400,Volume=100.3},12 new Bigtruck() { Owner="e",Mileage=500,Volume=100.4},13 new Bigtruck() { Owner="f",Mileage=600,Volume=100.5}14 };15 16 var castList = list0.Cast<Car>();17 var oftypeList = list0.OfType<Bigtruck>();18 19 Console.WriteLine(castList.Count()); //620 Console.WriteLine(oftypeList.Count()); //5
使用Cast<T>()會把列表中元素轉換成T類型,遇到不能轉換的元素將報錯,而OfType<T>()會嘗試轉換每個元素到T類型,遇到不能轉換的元素則跳過。當顯式聲明使用範圍變數時,會在轉譯時調用Cast()方法。如
1 var result2 = from Car e in list2 select e;3 result2 = list.Cast<Car>().Select(e => e);
運算式會轉譯為第三行的代碼。
- LINQ是以資料列表為基礎,在任何地方可能的地方進行流處理
- 建立一個查詢運算式,不會立刻執行,大部分操作都會順延強制
- C#3的查詢運算式包括一個把運算式轉換成普通C#代碼的預先處理階段,接著使用類型推斷、重載、Lambda運算式等這些常規操作來恰當地對轉換後的代碼進行編譯
- 在查詢運算式中聲明的變數:它們僅僅是範圍變數,通過它們你可以在查詢運算式內部一致地引用資料
請斧正。
20.C#LINQ基礎和簡單使用(十一章11.1-11.2)