寫在前面
系列文章
常見關鍵字
總結
前面的幾篇文章算是對linq的鋪墊,從本篇開始將進行linq的語法及實踐。
Linq之Lambda表達式初步認識
Linq之Lambda進階
Linq之隱式類型、自動屬性、初始化器、匿名類
Linq之擴展方法
Linq之Expression初見
Linq之Expression進階
Linq之Expression高級篇(常用表達式類型)
什麼情況下使用linq呢?
可以這樣說,只要是實現了IEnumerable<T>接口的對象都可以使用Linq的語法來查詢。
而對於只實現了IEnumerable接口而沒有實現IEnumerable<T>的對象可以通過如下的方法
public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source);
來將IEnumerable接口轉為IEnumerable<T>(例如ArrayList)。
那麼在linq中常見的關鍵字有那些呢?
在c#3.0中,為linq引入了一下幾個關鍵字:from join where group into let orderby select等。
如果你用過sql,那麼你對它們並不陌生。語法很簡單,這裡就對每個簡單的列舉一個例子,以便你快速的回憶起他們的用法。
from
from子句是一個Linq查詢的開始,任何一個Linq語句都是以from開始,from子句指定查詢的容器,和在此語句有效的局部變量。from子句的語法為:
from localParameter in Source
從上面的語法你會發現和foreach何其相似。
foreach(var item in source) { //循環體 }
通過上面的對比,你應該對localParameter和Source有個清楚的認識了。不過在linq中Source必須是實現IEnumerable<T>的對象。下面看一個例子:
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 List<int> lstInts = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 6 IEnumerable<int> query = from i in lstInts 7 select i; 8 foreach (var item in query) 9 { 10 Console.WriteLine(item); 11 } 12 Console.Read(); 13 } 14 }
結果
舉得例子其實並沒有實際意義,通過這樣的例子,希望對linq有個大概的認識。由於source實現自IEnumerable<T>泛型接口,T可以由source推導出來,在這個例子中T為int。
那麼對沒有實現IEnumerable<T>而只實現IEnumerable接口的ArrayList,該如何使用linq呢?
此時,就需要我們顯式指定局部變量的類型,或者是使用Cast轉為IEnumerable<T>
例如:
1 IEnumerable<int> q2 = from i in arry.Cast<int>() 2 select i; 3 //或者 4 var q3 = from int i in arry 5 select i;
select
對查詢結果進行投影,有時我們並不需要所有的列,而只需要其中的某幾個列的值,此時,select是非常有用的。
下面看一個例子
假如我們有這樣一個類
1 class Person 2 { 3 public int ID { set; get; } 4 public string Name { set; get; } 5 public int Age { set; get; } 6 }
我們有這樣一個集合
1 List<Person> persons = new List<Person>() 2 { 3 new Person(){ ID=1, Age=20, Name="wolfy"}, 4 new Person(){ID=2,Age=22,Name="angle"} 5 };
現在我們要取出集合中所有人的姓名,即只投影某一列。
1 var pNames = from p in persons 2 select p.Name;
當然我們也可以投影一個集合,此時就需要使用匿名類。
1 var persons2 = from p in persons 2 select new { p.Name, p.Age }; 3 //或者 4 var persons3 = from p in persons 5 select new { name = p.Name, age = p.Age }; 6 foreach (var item in persons3) 7 { 8 Console.WriteLine(item.name + " " + item.age); 9 }
persons3中,在匿名類中,你可以顯示的指定投影的列名。
where
對source中的數據進行篩選,看一個例子,選出所有的成年人的姓名。
var persons4 = from p in persons where p.Age > 18 select p.Name;
join
用法類似sql中join,將兩個source以某種關系進行關聯。
一個例子,查出公司為“北京能力有限公司”的人的名字和所在的公司名字。
1 class Person 2 { 3 public int ID { set; get; } 4 public string Name { set; get; } 5 public int Age { set; get; } 6 public int CompanyID { set; get; } 7 } 8 class Company 9 { 10 public int ID { set; get; } 11 public string Name { set; get; } 12 }
1 List<Person> persons = new List<Person>() 2 { 3 new Person(){ ID=1, Age=20, Name="wolfy",CompanyID=1}, 4 new Person(){ID=2,Age=22,Name="angle",CompanyID=2} 5 }; 6 List<Company> companys = new List<Company>() 7 { 8 new Company(){ ID=1, Name="北京能力有限公司"}, 9 new Company(){ID=2,Name="北京無能有限公司"} 10 }; 11 var result = from p in persons 12 join c in companys on p.CompanyID equals c.ID 13 where c.Name=="北京能力有限公司" 14 select new { Name = p.Name, CompanyName = c.Name }; 15 foreach (var item in result) 16 { 17 Console.WriteLine(item.Name + " " + item.CompanyName); 18 }
結果
注意
join子句只能使用equals或者是not equal而不能用其他運算符(==都不行)。而equals運算符左邊必須聯接的左部,右邊為右部,不能調換的,否則編譯不能通過。
into和group
into子句用於將join或者是group子句的結果進一步持續化,包裝成為一個System.Linq.IGrouping<TKey, TElement>對象,而且IGrouping繼承自IEnumerable<TElement>,IGrouping接口提供分組的鍵和,該鍵下所包含的集合。
下面看一個例子
1 List<string> lstNames = new List<string>() { "zhangsan", "lisi", "wanger", "mazi", "zhangwuji" }; 2 var result2 = from n in lstNames 3 group n by n.Length into g 4 select new { g.Key, values = g }; 5 foreach (var group in result2) 6 { 7 Console.WriteLine("{0}:", group.Key); 8 foreach (var item in group.values) 9 { 10 Console.WriteLine(item); 11 } 12 }
結果
let
let子句用於在查詢中添加一個新的局部變量,使其在後面的查詢中可見,類似sql中為as關鍵字為字段起別名。
1 var persons4 = from p in persons 2 let age = p.Age 3 where age > 18 4 select p.Name;
Take Skip
用於選取前幾個或者和跳過前幾個,如選擇第11到20個則可以
1 query.Skip(10).Take(10);
跳過前十個,然後再取10條數據。
OrderBy OrderByDescending
query.OrderBy(c => c.Length);
本篇文章介紹了在linq中常見的關鍵字,他們的作用可以類比sql中的用法。當然還有一些關鍵字,比如:Distinct Union Intersect Except,這些就不再舉例了。感興趣的可以自己動手試一試。
其它的樣例代碼可參考:https://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b
參考文章
http://kb.cnblogs.com/page/100043/