.NET中數據訪問方式之LINQ

SQL XML 程序員 Visual Studio 沈超 2017-04-10

語言集成查詢(Language-Integrated Query),簡稱LINQ,.NET中的LINQ體系如下圖所示:

.NET中數據訪問方式之LINQ

LINQ Hierarchy

在編程語言層次,LINQ對於不同的數據源提供了相同的查詢語法,方便了程序員操作不同的數據源。

可查詢類型

LINQ之所以能夠使用相同的語法操作不同的數據源,是因為和LINQ直接打交道的是可查詢類型而非數據源,在LINQ中,直接或間接實現了IEnumerable<T>接口的類型稱為可查詢類型, .NET中如:List<T>Dictionary<TKey,TValue>,數組(由CLR負責隱式實現IEnumerable<T>接口)等,實現了IEnumerable<T>接口。

IQueryable<out T>繼承自IEnumerable<T>,是個標記接口。

可查詢類型無需額外操作即可進行LINQ操作,若數據源在內存中不以可查詢類型的形式存在,那麼LINQ提供程序必須要先將數據源轉換為可查詢類型,如LINQ to XML將XML文件轉換為可查詢的XElement類型:

XElement contacts = XElement.Load(@"c:\myContactList.xml");

LINQ 提供程序

LINQ提供程序提供了對特定的數據源進行標準的LINQ操作及一些擴展操作(如:LINQ to XML),不同的LINQ提供程序對於一些相同名稱的擴展方法會提供不同的實現方式。.NET中預定義的LINQ提供程序包括:LINQ to Object、LINQ to XML (C#)、LINQ to SQL、LINQ to DataSet、LINQ to Entities。

LINQ to SQL不建議使用,用LINQ to Entities來替代。

LINQ查詢包含三個步驟:

  1. 獲取數據源

  2. 創建查詢語句

  3. 執行查詢

LINQ查詢方式

  • LINQ 表達式

    from關鍵字開頭,select關鍵字結尾。

  • 擴展方法

    System.Linq.Enumerable類和System.Linq.Queryable類,分別針對IEnumerable<T>IQueryable<T>接口進行的擴展。

  • LINQ 表達式和擴展方法混合使用

    (from e in Employees

    where e.Salary>8000

    select e).ToList()

LINQ表達式和擴展方法對比:

LINQ表達式和擴展方法在編譯後的代碼沒有什麼區別

  • 對於排序、分組、聯合查詢使用LINQ表達式更為方便

//已排序為例,使用年齡、姓名、郵箱進行排序,

//LINQ表達式中使用逗號分隔排序字段,而擴展方法則需要多次調用相應的擴展方法

var result= from e in Employees

where e.Age>50 && e.Salary>8000

orderby e.Age,e.Name,e.Email

select e;

//等價的擴展方法

var result=Employees

.Where(e=>e.Age>50 && e.Salary>8000)

.OrderBy(e=>e.Age)

.ThenBy(e=>e.Name)

.ThenBy(e=>e.Email);

  • 擴展方法能夠提供比LINQ表達式更復雜的查詢

//取第26行到36行範圍內的數據

var result=Employees.Skip(25).Take(10);

//使用LINQ表達式我表示寫不出來......

LINQ查詢特點:

  • 延遲查詢

    在聲明查詢表達式時不會執行查詢,而是在迭代查詢變量時才進行查詢。

    .NET中數據訪問方式之LINQ

    MSDN上的經典LINQ查詢流程圖(延遲查詢)

  • 立即查詢

    若查詢表達式返回單個值或者使用了ToList<T>ToArray<T>Count()等方法也會執行立即查詢。

LINQ表達式中的查詢關鍵字

表格中的英文沒什麼難點,就不翻譯了 :)

關鍵字描述
fromSpecifies a data source and a range variable (similar to an iteration variable).
whereFilters source elements based on one or more Boolean expressions separated by logical AND and OR operators.
selectSpecifies the type and shape that the elements in the returned sequence will have when the query is executed.
groupGroups query results according to a specified key value.
intoProvides an identifier that can serve as a reference to the results of a join, group or select clause.
orderbySorts query results in ascending or descending order based on the default comparer for the element type.
joinJoins two data sources based on an equality comparison between two specified matching criteria.
letIntroduces a range variable to store sub-expression results in a query expression.
inContextual keyword in ajoinclause.
onContextual keyword in ajoinclause.
equalsContextual keyword in ajoinclause.
byContextual keyword in agroupclause.
ascendingContextual keyword in anorderbyclause.
descendingContextual keyword in anorderbyclause.

兩個接口

在LINQ中,一個查詢表達式被編譯為表達式樹或者委託,查詢結果為IEnumerable<T>類型則被編譯為委託,查詢結果是IQueryableIQueryable<T>類型則被編譯為表達式樹,在運行時表達式樹會被解析為適合於數據源的查詢語句。

  • System.Collection.IEnumerable

    IEnumerable先將數據放到內存中,然後在執行過濾操作(如果有的話),適合於對內存中的數據進行查詢操作,如:LINQ to XMLLINQ to Object

  • System.Linq.IQueryable

    在執行查詢操作時,IQueryable先在服務器端進行過濾操作(如果有的話),然後再將數據放到內存中。

    IQueryable適合使用對內存外(如數據庫)的數據進行查詢操作,如:LINQ to Entities

兩個命名空間

System.Linq

System.Linq命名空間中包含用於LINQ查詢的類和接口

System.Linq.Expressions

System.Linq.Expressions 命名空間包含了用於創建表達式樹的類、 接口。

LINQ的優缺點

優點

  1. 對不同的數據源提供了幾乎一致的查詢操作,這可使我們更多的去關注業務邏輯而非對數據源的操作

  2. 提供編譯期的類型檢查

  3. 在書寫LINQ查詢表達式時可以使用Visual Studio的智能提示

  4. 調試方便

缺點

  1. 對於複雜的查詢操作顯得力不從心

  2. 容易寫出性能不高的查詢表達式

結語

本篇是自己學習LINQ的總結,不求面面俱到。通篇以文字敘述為主,輔以少量代碼,若有錯誤希望大家指出。

工具推薦

LINQ Pad是一款輕量級的數據查詢工具,在LINQ Pad中可以使用LINQ表達式、擴展方法、SQL語句等對數據庫進行操作,簡單易用功能強大。

.NET中數據訪問方式之LINQ

相關推薦

推薦中...