1. 程式人生 > 程式設計 >詳解LINQ入門(上篇)

詳解LINQ入門(上篇)

前 言

最近和我們老大一起做技術面試(我是旁聽的),發現前來面試的沒幾個掌握甚至是丁點了解LINQ。這讓我很納悶,LINQ伴隨2008一起釋出至今難道大家真的沒時間去了解一下或者學習一下這個應用基礎嗎。甚至問及有些人LINQ是什麼,答題者想都不想 LINQ TO SQL, 崩潰!沒錯,LINQ是可以TO SQL,但是除了SQL,LINQ就無所作為了?非也。因此在這裡和大家一起分享學習LINQ。本文適合以下讀者,如果你是不符合者請賞臉捧個場,3Q

  • 從未觸碰過LINQ的
  • 對LINQ有過了解但是從未實戰過的
  • 打算學習LINQ的

簡 介

LINQ 是什麼?引用官方術語“語言整合查詢 (LINQ) 是 Visual Studio 2008 和 .NET work 3.5 版中引入的一項創新功能,它在物件領域和資料領域之間架起了一座橋樑。” 那麼LINQ給我們帶來了什麼,請看以下例子:

問:有序列A=int[]{1,2,3,4,5,6,7,8,0}; B=int[]{2,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操作它。且在沒有經過其他處理的情況下將返回一個新的IEnumerable序列,注意LINQ有一個特性“延遲載入”這個將在後續說明。

3. 關鍵字(摘自MSDN):  

    from : 指定資料來源和範圍變數(類似於迭代變數)。

    where: 根據一個或多個由邏輯“與”和邏輯“或”運算子(&& 或 ||)分隔的布林表示式篩選源元素。

    select: 指定當執行查詢時返回的序列中的元素將具有的型別和形式。

    group: 按照指定的鍵值對查詢結果進行分組。

    into: 提供一個識別符號,它可以充當對 join、group 或 select 子句的結果的引用。

    orderby: 基於元素型別的預設比較器按升序或降序對查詢結果進行排序。

    join: 基於兩個指定匹配條件之間的相等比較來聯接兩個資料來源。

    let: 引入一個用於儲存查詢表示式中的子表示式結果的範圍變數。

    in: join 子句中的上下文關鍵字。

    on: join 子句中的上下文關鍵字。

    equals: join 子句中的上下文關鍵字。

    by: group 子句中的上下文關鍵字。

    ascending:orderby 子句中的上下文關鍵字。

    descending:orderby 子句中的上下文關鍵字。

  4. 語法說明,每個LINQ語句都以from作為開頭,以select作為結束,這點和T-SQL語法不通的切記先入為主的思考。其他關鍵字如where則類似T-SQL作為篩選判斷條件。

樣例:IEnumerable<T> nums = from n in nums where .... orderby... select....

擴 展

從 .net 3.0 開始 MS 就給我們引進了其他一些新的特性,由於篇幅關係在這裡給大家簡單的介紹幾個LINQ常用到的特性:

  1. 關鍵字 var :

    指示編譯器根據初始化語句右側的表示式推斷變數的型別。 推斷型別可以是內建型別、匿名型別、使用者定義型別或 .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;

注意,在此示例裡,關鍵字 into 不是必須的,使用 into 時,必須繼續編寫該查詢,並最終用一個 select 語句或另一個 group 子句結束該查詢。

內聯查詢

var query= from obj1 in objs1
      join obj2 in objs2 on obj1.ID equals obj2.ID
      select new { A= obj1.Property,B = obj2.Property };

左外聯查詢

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 新特性靜態擴充套件方法(後續介紹不影響理解)DefaultIfEmpty():如果序列為空,則返回一個具有預設值的單一例項集合

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。