詳解LINQ入門(上篇)
前 言
最近和我們老大一起做技術(shù)面試(我是旁聽的),發(fā)現(xiàn)前來面試的沒幾個掌握甚至是丁點了解LINQ。這讓我很納悶,LINQ伴隨2008一起發(fā)布至今難道大家真的沒時間去了解一下或者學(xué)習(xí)一下這個應(yīng)用基礎(chǔ)嗎。甚至問及有些人LINQ是什么,答題者想都不想 LINQ TO SQL, 崩潰!沒錯,LINQ是可以TO SQL,但是除了SQL,LINQ就無所作為了?非也。因此在這里和大家一起分享學(xué)習(xí)LINQ。本文適合以下讀者, 如果你是不符合者請賞臉捧個場,3Q
- 從未觸碰過LINQ的
- 對LINQ有過了解但是從未實戰(zhàn)過的
- 打算學(xué)習(xí)LINQ的
簡 介
LINQ 是什么?引用官方術(shù)語“語言集成查詢 (LINQ) 是 Visual Studio 2008 和 .NET work 3.5 版中引入的一項創(chuàng)新功能,它在對象領(lǐng)域和數(shù)據(jù)領(lǐng)域之間架起了一座橋梁?!?那么LINQ給我們帶來了什么,請看以下例子:
問:有序列A=int[]{1,2,3,4,5,6,7,8,0}; B=int[]{2,4,7,8,9}。請求出包含A和B共同值的序列C。
如果按照原來的思路,那么編碼也許如下:
說明:
List<int> c = new List<int>(); foreach(int a in A){ foreach(int b in b) { if (a==b) { c.add(a); } } }
說明:
是不是覺得上面這段雖然沒什么問題,但是很丑陋。如果我們引用LINQ來編寫呢:
IEnumerable<int> C = from a in A from b in B where a==b select a;
語 法
1. LINQ所處在的主要命名空間:System.Linq
2. LINQ的處理的核心對象就是IEnumerable可枚舉對象也包括了泛型枚舉,換句話說當你要處理的對象為IEnumerable類型對象時即可使用LINQ操作它。且在沒有經(jīng)過其他處理的情況下將返回一個新的IEnumerable序列,注意LINQ有一個特性“延遲加載”這個將在后續(xù)說明。
3. 關(guān)鍵字(摘自MSDN):
from : 指定數(shù)據(jù)源和范圍變量(類似于迭代變量)。
where: 根據(jù)一個或多個由邏輯“與”和邏輯“或”運算符(&& 或 ||)分隔的布爾表達式篩選源元素。
select: 指定當執(zhí)行查詢時返回的序列中的元素將具有的類型和形式。
group: 按照指定的鍵值對查詢結(jié)果進行分組。
into: 提供一個標識符,它可以充當對 join、group 或 select 子句的結(jié)果的引用。
orderby: 基于元素類型的默認比較器按升序或降序?qū)Σ樵兘Y(jié)果進行排序。
join: 基于兩個指定匹配條件之間的相等比較來聯(lián)接兩個數(shù)據(jù)源。
let: 引入一個用于存儲查詢表達式中的子表達式結(jié)果的范圍變量。
in: join 子句中的上下文關(guān)鍵字。
on: join 子句中的上下文關(guān)鍵字。
equals: join 子句中的上下文關(guān)鍵字。
by: group 子句中的上下文關(guān)鍵字。
ascending:orderby 子句中的上下文關(guān)鍵字。
descending:orderby 子句中的上下文關(guān)鍵字。
4. 語法說明,每個LINQ語句都以from作為開頭,以select作為結(jié)束,這點和T-SQL語法不通的切記先入為主的思考。其他關(guān)鍵字如where則類似T-SQL作為篩選判斷條件。
樣例:IEnumerable<T> nums = from n in nums where .... orderby... select....
擴 展
從 .net 3.0 開始 MS 就給我們引進了其他一些新的特性,由于篇幅關(guān)系在這里給大家簡單的介紹幾個LINQ常用到的特性:
1. 關(guān)鍵字 var :
指示編譯器根據(jù)初始化語句右側(cè)的表達式推斷變量的類型。 推斷類型可以是內(nèi)置類型、匿名類型、用戶定義類型或 .NET Framework 類庫中定義的類型。這樣我們就可以在上述的LINQ表達式中 例如可簡寫為: var nums = from n in nums where .... orderby... select....
2. 匿名類型:
匿名類型提供了一種方便的方法,可用來將一組只讀屬性封裝到單個對象中,而無需首先顯式定義一個類型。 類型名由編譯器生成,并且不能在源代碼級使用。 每個屬性的類型由編譯器推斷。例如:var obj = new {A="a", B="b"}; 而LINQ則可以為 var nums = from obj in objs select new {obj.A, obj.B}
案 例
普通查詢
var query = from num in num select num.ProperyA
篩選查詢
var query = from obj in objs where obj.ProperyA > Condition select obj
分組查詢
var query = from obj in objs group obj by obj.PropertyA into g orderby g.Key select g;
注意,在此示例里,關(guān)鍵字 into 不是必須的,使用 into 時,必須繼續(xù)編寫該查詢,并最終用一個 select 語句或另一個 group 子句結(jié)束該查詢。
內(nèi)聯(lián)查詢
var query= from obj1 in objs1 join obj2 in objs2 on obj1.ID equals obj2.ID select new { A= obj1.Property, B = obj2.Property };
左外聯(lián)查詢
var query = from obj1 in objs1 join obj2 in objs2 on obj1.ID equals obj2.Obj1ID into g from subpet in g.DefaultIfEmpty() select new { P1 = obj1.P1, P2 = (subpet == null ? null : subpet.P2 ) };
注意,此處涉及到.net 3.5 新特性靜態(tài)擴展方法(后續(xù)介紹不影響理解)DefaultIfEmpty():如果序列為空,則返回一個具有默認值的單一實例集合
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#利用反射來判斷對象是否包含某個屬性的實現(xiàn)方法
這篇文章主要介紹了C#利用反射來判斷對象是否包含某個屬性的實現(xiàn)方法,很有借鑒價值的一個技巧,需要的朋友可以參考下2014-08-08NumberToUpper數(shù)字轉(zhuǎn)中文詳解
本文介紹NumberToUpper數(shù)字轉(zhuǎn)中文的方法,大家參考使用吧2013-12-12C#中DataGridView導(dǎo)出Excel的兩種方法
這篇文章主要介紹了C#中DataGridView導(dǎo)出Excel的兩種方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01