LINQ(語言集成查詢)

 

LINQ,語言集成查詢(Language Integrated Query)是一組用於 c#Visual Basic語言的擴展。它容許編寫C#或者Visual Basic代碼以查詢數據庫相同的方式操做內存數據。
中文名
語言集成查詢
外文名
Language Integrated Query
開發公司
微軟
語    言
C#,Visual Basic

基本含義

編輯
從技術角度而言,LINQ定義了大約40個查詢操做符,如select、from、in、where以及order by( C#中)。使用這些操做符能夠編寫查詢語句。不過,這些查詢還能夠基於不少類型的數據,每一個數據類型都須要一個單獨的LINQ類型。
通過了最近 20 年, 面向對象 編程技術( object-oriented (OO) programming technologies )在工業領域的應用已經進入了一個穩定的發展階段。程序員如今都已經認同像 類(classes)、對象(objects)、方法(methods)這樣的語言特性。考察如今和下一代的技術,一個新的編程技術的重大挑戰開始呈現出來,即 面向對象技術誕生以來並無解決下降訪問和整合信息數據( accessing and integrating information )的複雜度的問題。其中兩個最主要訪問的數據源與數據庫( database)和 XML標準通用標記語言下的一個應用)相關。
LINQ 提供了一條更常規的途徑即給 .Net Framework添加一些能夠應用於全部信息源( all sources of information )的具備多種用途( general-purpose )的語法查詢特性( query facilities ),這是比向開發語言和運行時( runtime )添加一些關係數據( relational )特性或者相似 XML 特性( XML-specific )更好的方式。這些語法特性就叫作 .NET Language Integrated Query (LINQ) 。
包含 DLinq 和 XLinq。

相關概念

編輯
  1. LINQ的讀法:(1)lin k (2)lin q
  2. LINQ的全稱:Language-Integrated Query
  3. LINQ的關鍵詞:from, select, in, where, group by, orderby, …
  4. LINQ的寫法:
1) from 臨時變量 in 實現IEnumerable<T>接口的對象
[orderby 條件]
[group by 條件]
select 臨時變量中被查詢的值
2) 實現IEnumerable<T>接口的對象.LINQ方法名(lambda表達式)。如:
string input = "hello world";
int count = input.Count(w=>w == 'o'); //查詢字母o出現的次數
注意:可以使用LINQ的對象須要實現IEnumerable<T>接口。而且LINQ的查詢 表達式是在最近一次建立對 象時才被編譯的。
5. 命名空間(.NET Framework):System.Linq;
注意:Linq是在.NET Framework 3.5 中出現的技術,因此在建立新項目的時候必需要選3.5或者更高版 本,不然沒法使用。選擇3.5或更高版本的 .NET Framework以後,建立類文件中會自動包含System.Linq 的命名空間。

語法實例

編輯
C#3.0 LINQ 查詢語法
首先來看一個很簡單的LINQ查詢例子,查詢一個int 數組中小於5的數字,並按照大小順序排列:
static void Main(string[] args)
{
int[] arr = new int[] { 8, 5, 89, 41, 1, 2, 3, 65, 1 };
var m = from n in arr where n < 5 orderby n descending select n;//小於5,而且倒敘排列顯示
foreach (var n in m)
{
Console.WriteLine(n);
}
Console.ReadLine();
}
上述代碼除了LINQ查詢語法外,其餘都是咱們所熟悉的語法,而LINQ查詢語法跟SQL查詢語法很類似,除了前後順序。
Q:爲什麼 LINQ 查詢語法是以 from 關鍵字開頭的,而不是以 select 關鍵字開頭的?select 開頭這種寫法跟SQL的寫法更接近,更易懂呀?
A:簡單來講,爲了IDE的智能感知(Intellisence)這個功能,select 關鍵字放在後面了。
編程語言以 select 開頭寫LINQ查詢語法不是沒出現過,你若是使用過2005年的VB9 CTP 版本,那時候VB9的LINQ查詢語法就是 select 關鍵字在前面,可是 select 關鍵字在前面,在作智能感知(Intelisence)時候就很頭大。通過微軟IDE組的權衡,肯定了把 from 關鍵字放在最前面。
那時候 VB9 LINQ的查詢語法仍是 select 參數在最前面。不事後來 VB9 測試版改爲了跟 C# 同樣的作法, from 關鍵字放在最前面了。
更詳細的解釋,來自裝配腦殼
假設你要書寫這樣的代碼:Select p. Name, p.Age From p In persons Where xxx ,代碼是一個個字符輸入的。
咱們在寫到 p in persons 以前,p 的類型是沒法推測的,因此寫 Select p. 的時候,Name之類的屬性不會彈出智能提示來。
這樣就須要先去寫 From 這句,再回來寫 Select。
微軟IDE組通過反覆考慮決定,還不如就把 Select 寫到後面了。因而編程語言中的寫法就肯定這樣來寫了。
VB9 的這個變化能夠參看這篇博客:
Select/From vs. From/Select revisited...
咱們再來看一個稍稍複雜的LINQ查詢:
在咱們列舉的語言字符串中,咱們但願按照字符長短,分類列舉出來,實現代碼以下:
static void Main(string[] args)
{
string[] languages = { "Java", "C#", "C++", "Delphi", "VB.net", "VC.net", "C++Builder", "Kylix", "Perl", "Python" };
var query = from item in languages
group item by item.Length into lengthGroups
orderby lengthGroups.Key
select lengthGroups;
foreach (var item in query)
{
Console.WriteLine("strings of length{0}", item.Key);
foreach (var val in item)
{
Console.WriteLine(val);
}
}
Console.ReadLine();
}
其中的 into 關鍵字表示 將前一個查詢的結果視爲後續查詢的生成器,這裏是跟 group by 一塊兒使用的。
LINQ中的Group by不要跟 SQL 中的Group by 混淆, SQL因爲是二維結構,Group by 的一些邏輯受二維結構的約束,沒法像 LINQ 中的Group by 這麼靈活。
事實上,LINQ的查詢語法存在如下兩種形式:
查詢方法方式:(Methord Syntax)
主要利用System.Linq.Enumerable類中定義的擴展方法和Lambda表達式方式進行查詢
查詢語句方式:(Query Syntax)一種更接近SQL語法的查詢方式,可讀性更好。

原理淺析

編輯
LINQ(Language Integrated Query)是Visual Studio 2008中的領軍人物。藉助於LINQ技術,咱們可使用一種相似SQL的語法來查詢任何形式的數據。目前爲止LINQ所支持的 數據源SQL ServerOracleXML標準通用標記語言下的一個應用)以及內存中的數據集合。開發人員也可使用其提供的擴展框架添加更多的數據源,例如MySQL、Amazon甚至是 GoogleDesktop。
通常來說,這類查詢語句的一個重要特色就是能夠並行化執行。雖然有些狀況下並行可能會帶來一些問題,但這種狀況很是少見。這樣也就水到渠成地引出了PLINQ這個 並行處理的LINQ類庫。
PLINQ原名爲Parallel LINQ,支持XML和內存中的數據集合。執行於遠程服務器上的查詢語句(例如LINQ to SQL)顯然沒法實現這個功能。
將LINQ語句轉換爲PLINQ語句極爲簡單——只須要在查詢語句中From子句所指定的數據源的最後添加.AsParallel()便可。隨後Where、OrderBy和Select子句將自動改成調用這個並行的LINQ版本。
據MSDN Magazine介紹,PLINQ能夠以三種方式執行。第一種是管道處理:一個線程用來讀取數據源,而其餘的線程則用來處理查詢語句,兩者同步進行——雖然這個單一的消費線程可能並不那麼容易與多個生產 線程同步。不過如果可以仔細配置好負載平衡的話,仍然會極大地減小內存佔用。
第二種模式叫作「stop and go」,用於處理 結果集須要被一次返回時(例如調用ToList、ToArray或對結果排序)的狀況。在這種模式下,將依次完成各個處理過程,並將結果統一返回給消費線程。這個模式在性能上將優於第一種模式,由於它省去了用來保持線程同步所花費的開銷。
最後一種方法叫作「inverted enumeration」。該方法並不須要實現收集到全部的輸出,而後在單一的線程中處理,而是將最終調用的函數經過ForAll擴展傳遞到每一個線程中。這是目前爲止最快的一種處理模式,不過這須要傳遞到ForAll中的函數是 線程安全的,且最好不包含任何lock之類的互斥語句。
如果PLINQ中任意的一個線程 拋出異常,那麼全部的其餘線程將會被終止。如果拋出了多個異常,那麼這些異常將被組合成一個MultipleFailuresException類型的異常,但每一個異常的調用 堆棧仍會被保留。

使用優勢

編輯
一、無需複雜學習過程便可上手
二、編寫更少代碼便可建立完整應用。
三、更快開發錯誤更少的應用程序。
四、無需求助奇怪的編程技巧就可合併 數據源
五、可以大幅減小過程控制語句的代碼塊,使代碼的可讀性和可維護性大幅提升。
六、任何對象或數據源均可以定製實現Linq 適配器,爲數據交互帶來真正方便。

函數支持

編輯
支持如下公共語言運行時 ( CLR) 方法和屬性,由於它們能夠在查詢表達式中進行轉換以包含在 OData服務的請求 URI 中:
String成員 支持的 OData 函數
Concat
string concat(string p0, string p1)
Contains
bool substringof(string p0, string p1)
EndsWith
bool endswith(string p0, string p1)
IndexOf
int indexof(string p0, string p1)
Length
int length(string p0)
Replace
string replace(string p0, string find, string replace)
Substring
string substring(string p0, int pos)
Substring
string substring(string p0, int pos, int length)
ToLower
string tolower(string p0)
ToUpper
string toupper(string p0)
Trim
string trim(string p0)
DateTime成員1 支持的 OData 函數
Day
int day(DateTime p0)
Hour
int hour(DateTime p0)
Minute
int minute(DateTime p0)
Month
int month(DateTime p0)
Second
int second(DateTime p0)
Year
int year(DateTime p0)
1也支持 Visual Basic中等效的Microsoft.VisualBasic.DateAndTime的日期和時間屬性以及DatePart方法。
Math成員 支持的 OData 函數
Ceiling
decimal ceiling(decimal p0)
Ceiling
double ceiling(double p0)
Floor
decimal floor(decimal p0)
Floor
double floor(double p0)
Round
decimal round(decimal p0)
Round
double round(double p0)
Expression成員 支持的 OData 函數
TypeIs
bool isof(type p0)
客戶端或許還能夠在客戶端上計算其餘 CLR 函數。對於沒法在客戶端上計算以及沒法轉換爲有效請求URI以便在服務器上計算的任何表達式,將引起NotSupportedException。
相關文章
相關標籤/搜索