首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

LINQ 解釋查詢深度解析:IQueryable、表達式樹與 AsEnumerable

     編輯:關於SqlServer

兩種查詢架構

LINQ 提供平行的雙重架構:

  • 本地查詢:針對 IEnumerable<T>,使用 Enumerable 操作符,以委托執行。
  • 解釋查詢:針對 IQueryable<T>,使用 Queryable 操作符,以表達式樹在執行時解析並轉譯(如 SQL)。

.NET 內建兩大 IQueryable 實作:LINQ to SQL 與 LINQ to Entities。AsQueryable() 可將任何可列舉集合包裝為 IQueryable。

查詢翻譯過程

以查詢包含 "a" 的客戶名稱為例:

var query = from c in customers
            where c.Name.Contains("a")
            orderby c.Name.Length
            select c.Name.ToUpper();

編譯器先轉為 Lambda 語法,再解析操作符。因 customers 為 Table<Customer>(實作 IQueryable),編譯器選擇 Queryable.Where,其簽名接受 Expression<Func<T, bool>>,導致 Lambda 被解析為表達式樹而非委托。LINQ to SQL 隨後將表達式樹翻譯為 SQL:

SELECT UPPER([Name]) FROM [Customer] WHERE [Name] LIKE '%a%' ORDER BY LEN([Name])

執行模型

解釋查詢同樣遵循延遲執行:只有列舉時才產生 SQL。重複列舉會重複查詢資料庫,需注意效能。執行時,外層序列會走訪整棵表達式樹並一次性翻譯為單一 SQL 陳述式。

與本地查詢不同,擴展 IQueryable 極為困難:自訂擴展方法無法被遠端提供者理解,會導致與特定提供者綁定,失去互通性。此外,某些 LINQ 標準操作可能無法翻譯為 SQL,視資料庫而定。

AsEnumerable:強制本地執行

AsEnumerable() 將 IQueryable 轉為 IEnumerable,強制後續操作在本地執行。例如資料庫不支援 Regex,可先篩選主題再本地過濾內容:

var query = dataContext.Articles
    .Where(a => a.Topic == "LINQ")
    .AsEnumerable()
    .Where(a => reg.Matches(a.Content).Count > 500);

優於 ToList() 之處在於保持延遲執行且不建立中間集合。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved