23 七月, 2007 12:17
何謂 LINQ
程式語言隨著時間演進,一再沉澱經驗與抽象後,以簡練直觀的語法解決具有共通特徵的各式問題。Visual Studio 2008(程式碼名稱為 Orcas)、C# 3.0 與 VB.NET 9.0 後將支援新的語法 Language Integrated Query(LINQ),想一體解決多樣的資料存取。它是由 Anders Hejlsberg 所主導。Anders 曾打造了 Turbo Pascal、Delphi、Visual J++、C# 等叫好叫座的產品,單憑這位殺手應用創造者的眼光,LINQ 就不可小覷。
LINQ 是一系列語言延伸模組,以型別安全的方式支援資料查詢。期待隔絕各種資料的特性,不管是各廠家資料庫的 SQL 方言,或是 XML 的 DOM、XQuery 或 XPath,抑或是物件集合的屬性存取。以共通的方式完成資料操作,如:挑選、比對、排序、彙總…等等。期待減輕程式開發人員學習操作各種資料的負荷。
在即將來臨的 C# 3.0 / VB.NET 9.0 / Orcas 將支援之 LINQ 架構如下圖:
圖 1:C# 3.0 / VB.NET 9.0 / Orcas 將支援的 LINQ 架構
LINQ 藉由各語言編譯器將內嵌的 LINQ 語法轉譯成原本的 C# 或 VB.NET 程式碼,並呼叫相關的底層模組以實體維護資料。最後編譯成與 .NET Framework 2.0 CLR 相容的 IL,所以 CLR 本身並未增加與 LINQ 相關的模組,但 .NET Framework、Visual Studio 整合開發環境和程式語言需要增加相關功能和語法。
就筆者自己的感覺,LINQ 有以下的好處:
l 簡化大量的細節運作,將如何(how)取得資料換成要操作什麼(what)資料:這隱含存取最佳化交由專家來做,如 DB 引擎最佳化存取資料。
l 透過IEnumerable
l 平行運算:若要處理大量資料,程式設計師不容易撰寫 for 迴圈還包含平行運算。但 LINQ 轉譯成 C# 或 VB.NET 的程式碼時,可以平行運算的方式處理大量資料。
l 撰寫資料物件存取的過程中,可以 IntelliSense 和強型別檢查:相較於以往 ADO.NET 加上 SQL 語法,LINQ 比 typed dataset 直觀易懂,且應用更為廣泛。
就筆者與許多朋友聊到 LINQ 時,最多的詢問便是「未來是否不需要學 SQL 了?」個人認為,短時間不可能,LINQ 或許會減輕程式設計師對 SQL 的倚賴,但 LINQ 不會取代 SQL。它們各有一片天,LINQ 是程式設計師講的資料物件語言,SQL 是資料庫管理師對資料庫引擎講的語言,LINQ 是從應用程式處理資料的角度出發,但 SQL 關乎著整體資料庫伺服器有效且安全地活著的每一個細節。
而緊接的問題通常是:「將資料以物件來包裝,透過 entity 類別間接存取資料,那是否會有效率問題?」這筆者無法回答,尚待真實世界來證明。
@小標:LINQ 範例
你可以在 C# 中直接內嵌如下的語法:取得在 Customer 物件集合中,每個 Customer 的屬性 Country 值為 USA,按照 City 屬性由大到小排序,傳回以 CompanyName 和 City 兩個屬性的字串值所建立的新物件之集合:
var matchCustomers = from c in db.Customers
where c.Country == "USA"
orderby c.City descending
select new { c.CompanyName, c.City };
這句 LINQ 語法經由 C# 編譯器解析,傳回實做 IEnumerable
若不採用 LINQ 寫法,上述語法也可以寫成如下的方式:
var matchCustomers = db.Customers.Where(c => c.Country == "USA").OrderByDescending(c => c.City).Select(c => new { c.CompanyName, c.City });
哇,想我修習 .NET 數年,竟不知所云!?在此介紹一本入門書:「Introducing Microsoft LINQ」,Microsoft Press 出版。它讓你了解以往的 C# 和 VB.NET 各版本如何漸進地增加功能,最後演變出 LINQ 語法。
@小標:書籍內容
本書結構短小,僅六章加上一個附錄,各章的基本架構就是對應圖 1 的各個區塊。
第一章針對 LINQ 做總體概觀介紹,初讀此章時,覺得過於唐突,比照下載的完整範例程式碼還是不知所云,滿頭問號。待看完本書其他章節後,再回過頭看第一章,這回看懂了J
沒有任何進步是獨立完成的,因此本書第二、三章介紹為了支援 LINQ,或應該說若你要了解 LINQ 的運作原理,必須先熟悉 C# 與 VB.NET 的相關功能,約略表列如下:
l C# 2.0 提供的泛型(Generic)、匿名方法,與改良的委派和 Enumerators 與 Yield。
l C# 3.0 提供的 Local Type Inference、Lambda 運算式(Lambda Expressions)、延伸方法、隱含型別化區域變數(var)、匿名型別,和改良的物件初始設定式(Object Initialization Expressions)。
VB.NET 9.0 與 LINQ 語法相關的項目和前述 C# 相似,但少了 yield 關鍵字和匿名方法[1],多了對 XML 語法的支援和 Relaxed Keyword。
本書第四章介紹 LINQ 的語法結構,以及各種資料集合的運算,如連結、排序、過濾、群組、彙總..等 .NET Framework 預設為 LINQ 所提供的多種延伸方法。
第五章介紹 LINQ to ADO.NET 的特徵,這又分為 LINQ to SQL、LINQ to DataSet、LINQ to Entities ,本章簡述這三部分的建置與對應的 LINQ 語法:
l LINQ to SQL 透過 Orcas 的「LINQ to SQL File」範本產生出類別實體,以對應 SQL Server 資料庫內的某些資料表及其關聯,或是呼叫預存程序、函數等資料庫物件的方法後,撰寫資料處理的語法變得直觀易懂。搭配交易,以屬性和方法來新增、修改、刪除、查詢資料物件。
l LINQ to DataSet:由於 DataSet 可以視作記憶體中的小型資料庫,而賦予 DataSet 資料的方式也很多樣化,因此當 DataSet 有資料後,仍透過 LINQ 如同對一般資料庫的存取。
l Orcas 內建了產生 Entity Data Model(EDM) 的精靈,將資料存取物件的操作與資料實體儲存機制隔絕開來。LINQ 仍以相似的方式存取物件化的資料實體。此部分的相關資訊可參考本書的附錄。
第六章解釋何謂 LINQ to XML。由於 LINQ to XML API 嘗試簡化 XML 的相關技術,所以建置了一整組 X 開頭的類別,讓你以直觀的物件架構存取 XML 的各種節點,而不需要透過 W3C XML DOM 的繁複方式。本章除了說明這些 X 開頭的類別與以往 DOM 各物件方法之對應外,也闡述了如何透過 LINQ 維護 XML 資料。
在附錄中解釋了 ADO.NET Entity Framework 的架構,以及 Orcas 如何產生該架構下的三種檔案:
l Conceptual Schema Definition Language(CSDL):用來描述程式碼所依據的資料定義。
l Storage Schema Definition Language(SSDL):用來描述實體資料儲存區,如 SQL Server 對資料庫內各物件的定義。
l Mapping Schema Language(MSL):用來聯繫對應 CSDL 和 SSDL,因此 CSDL 與 SSDL 可以多對多對應,也就是資料操作與資料儲存能夠分開。
Orcas 參照 CSDL 會產生出代表資料的實體(entity)物件之 C# 程式碼,再經由 SSDL 和 MSL 結合到資料儲存的實體,如 SQL Server。當透過 LINQ 操作 ADO.NET Entity 時,可輕易完成資料維護與交易管理。
本書是為熟悉 C# 的程式設計師介紹 LINQ 語法,因此全書的文字內容並沒有完整的可執行範例[2],且未與 ASP.NET 或 Windows Form 等使用者介面技術整合。但對於 LINQ 的基本技術介紹得還算完整。由於只有 217 頁,逐頁讀完,也就對 LINQ 了然於胸J。若僅想熟悉 C# 或 VB.NET 二者之一,還可以在第二、三兩章中擇一,需要閱讀的分量就更少了。
但若不熟悉 C#,則你需要很大的耐心,先了解本文上述所表列 C# 的各項功能,並反覆閱讀本書,才能漸漸融會貫通。
最後,若你要購買本書,先有兩點考量:
l LINQ 還處於 Beta,明年推出的正式版可能仍有變化。
l 相對於內容分量,本書的價格偏於昂貴。
也因如此,它在 Amazon 的評價只有兩顆星。或許,它僅適合買書不考慮成本,以及對於新知充滿好奇的人。
最後,本書僅是 LINQ 的入門介紹,對於實際使用 LINQ 到日用習慣的資料操作,如與控制項做雙向資料繫結(DataBinding)以維護資料庫內資料、彈性地動態組 SQL 語法等,並未明確地交代。期待這一部分隨著 Orcas 步入正式版會有簡單且完整的解法。
@小標:相關閱讀
最後,筆者列出些相關的資源以延伸閱讀:
Anders Hejlsberg (C# 首席設計師)對 LINQ 定位的說明與實際親手示範其用法:
l http://channel9.msdn.com/showpost.aspx?postid=114680
MSDN 上介紹 LINQ 的文件:該篇專欄可幾近取代本書的第二章。
l http://msdn.microsoft.com/msdnmag/issues/07/06/csharp30/default.aspx?loc=zx
作者為本書所建置的網站,上有當作試閱的第一章,以及可下載的範例程式碼:
推文( 0 )
