從from開始
用過SQL的朋友都知道,最簡單的SQL語句SELECT record FROM tableName:獲取表中的所有記錄,那么對應於LINQ,其語法如下:
from record in tableName select record。
明顯的差異是將from語句放到了句首,此種語法方式只是為了適應Visual Studio中智能提示(試想如果將from子句放在后面,先輸入select語句,此時select的對象類型尚不確定,智能提示無法做出相應提示)
SQL語句是從數據庫表中查詢出記錄,而LINQ適應的數據源更廣,包括SQL Server數據庫、XML文檔、ADO.NET數據集以及所有支持IEnumerable及IEnumerable<T>接口的任意對象集合。
LINQ只是一種語法
LINQ查詢語句實際上和我們常用的foreach語句相似:中間語言(IL)中並沒有對應的foreach語句,編譯器最終會將foreach語句轉換為一些列的語句塊,例如:
string[] strs = new String[] {"One","Two","Three" };
foreach (String s in strs)
{
Console.WriteLine(s);
}
轉換為:
string[] strs = new String[] {"One","Two","Three" };
IEnumerator e = strs.GetEnumerator();
while (e.MoveNext())
{
Console.WriteLine(e.Current);
}
在.NET Framework 3.5中為IEnumerable<T>接口加入了大量的擴展方法,這些方法為LINQ提供了實現基礎(就像IEnumerable中GetEnumerator方法為foreach提供實現基礎一樣)
例如,IEnumerable中的Where擴展方法,它和LINQ中的where子句對應,用於篩選數據:
//使1用?Where方?法¨
IEnumerable<String> query = strs.Where(s => s.StartsWith("T"));
foreach (String s in query)
{
Console.WriteLine(s);
}
//使1用?query語?句?
query = from s in strs
where s.StartsWith("T")
select s;
foreach (String s in query)
{
Console.WriteLine(s);
}
題外話:如何為已知類型擴展方法:只需一個靜態類和靜態方法,在靜態方法中參數使用this關鍵字,以下為String類型新增一個AppendA方法:
public static class Extension
{
public static String AppendA(this String ins)
{
return ins + "AAA";
}
}
var關鍵字與匿名類型
var關鍵字指示編譯器推斷出變量的類型,例如:
var s = "Hello";
編譯器最終將s變量推斷為String類型,即最終按
String s = "Hello";
來生成中間代碼
在LINQ中我們可以通過var關鍵字來聲明查詢對象,而無需清楚最終我們查詢返回的具體類型:
var query = from s in strs
where s.StartsWith("T")
select s;
另一種情況,有時我們只需要返回對象的某些屬性,此時我們無需定義返回數據的類型,直接使用匿名類型:
1: var xxx = new { F1 = "Hello", F2 = "Hello2" };
2:
以下查詢只返回Programer類的Name和Position屬性:
public class Programer
{
public String Name { get; set; }
public String Language { get; set; }
public String Position { get; set; }
public Programer()
{
}
}
Programer[] ps = new Programer[] {
new Programer(){ Name="張?三y", Language="C#", Position="Leader"},
new Programer(){ Name="李?四?", Language="C#", Position="Coder"},
new Programer(){ Name="王?五?", Language="Java", Position="Coder"}
};
var queryPs = from p in ps
where p.Language == "C#"
select new { Name = p.Name, Position = p.Position };
foreach (var p in queryPs)
{
Console.WriteLine(String.Format("Name:{0}\t\tPosition:{1}", p.Name, p.Position));
}
查詢的執行時間
上述例子中LINQ語句是在foreach語句時才真正執行的,定義時只是定義了查詢語句,在進入foreach枚舉時才真正執行查詢語句。如果我們在定義時需要立即返回查詢結果可以使用ToArray或ToList方法(這兩個方法也是在.Net Fromework 3.5中為IEnumerable接口新增的擴展方法)。
var queryPs = (from p in ps
where p.Language == "C#"
select new { Name = p.Name, Position = p.Position }).ToArray();