LINQ to SQL語句(23)之動態查詢

作者: 李永京  來源: 博客園  發布時間: 2008-09-18 18:34  閱讀: 18428 次  推薦: 2   原文鏈接   [收藏]  
 
摘要:這個系列的第二十三篇,講解動態查詢。
[1] Select與Where
[2] OrderBy與Union

系列文章導航:

LINQ to SQL語句(1)之Where

LINQ to SQL語句(2)之Select/Distinct

LINQ to SQL語句(3)之Count/Sum/Min/Max/Avg

LINQ to SQL語句(4)之Join

LINQ to SQL語句(5)之Order By

LINQ to SQL語句(6)之Group By/Having

LINQ to SQL語句(7)之Exists/In/Any/All/Contains

LINQ to SQL語句(8)之Concat/Union/Intersect/Except

LINQ to SQL語句(9)之Top/Bottom和Paging和SqlMethods

LINQ to SQL語句(10)之Insert

LINQ to SQL語句(11)之Update

LINQ to SQL語句(12)之Delete和使用Attach

LINQ to SQL語句(13)之開放式并發控制和事務

LINQ to SQL語句(14)之Null語義和DateTime

LINQ to SQL語句(15)之String

LINQ to SQL語句(16)之對象標識

LINQ to SQL語句(17)之對象加載

LINQ to SQL語句(18)之運算符轉換

LINQ to SQL語句(19)之ADO.NET與LINQ to SQL

LINQ to SQL語句(20)之存儲過程

LINQ to SQL語句(21)之用戶定義函數

LINQ to SQL語句(22)之DataContext

LINQ to SQL語句(23)之動態查詢

LINQ to SQL語句(24)之視圖

LINQ to SQL語句(25)之繼承

LINQ簡介

adsfsaf

 

動態查詢

有這樣一個場景:應用程序可能會提供一個用戶界面,用戶可以使用該用戶界面指定一個或多個謂詞來篩選數據。這種情況在編譯時不知道查詢的細節,動態查詢將十分有用。

在LINQ中,Lambda表達式是許多標準查詢運算符的基礎,編譯器創建lambda表達式以捕獲基礎查詢方法(例如 Where、Select、Order By、Take While 以及其他方法)中定義的計算。表達式目錄樹用于針對數據源的結構化查詢,這些數據源實現IQueryable<T>。例如,LINQ to SQL 提供程序實現 IQueryable<T>接口,用于查詢關系數據存儲。C#和Visual Basic編譯器會針對此類數據源的查詢編譯為代碼,該代碼在運行時將生成一個表達式目錄樹。然后,查詢提供程序可以遍歷表達式目錄樹數據結構,并將其轉換為適合于數據源的查詢語言。

表達式目錄樹在LINQ中用于表示分配給類型為Expression<TDelegate>的變量的Lambda表達式。還可用于創建動態LINQ查詢。

System.Linq.Expressions命名空間提供用于手動生成表達式目錄樹的API。Expression類包含創建特定類型的表達式目錄樹節點的靜態工廠方法,例如,ParameterExpression(表示一個已命名的參數表達式)或 MethodCallExpression(表示一個方法調用)。編譯器生成的表達式目錄樹的根始終在類型Expression<TDelegate>的節點中,其中TDelegate是包含至多五個輸入參數的任何TDelegate委托;也就是說,其根節點是表示一個lambda表達式。

下面幾個例子描述如何使用表達式目錄樹來創建動態LINQ查詢。

1.Select

下面例子說明如何使用表達式樹依據 IQueryable 數據源構造一個動態查詢,查詢出每個顧客的ContactName,并用GetCommand方法獲取其生成SQL語句。

//依據IQueryable數據源構造一個查詢
IQueryable<Customer> custs = db.Customers;
//組建一個表達式樹來創建一個參數
ParameterExpression param = 
    Expression.Parameter(typeof(Customer), "c");
//組建表達式樹:c.ContactName
Expression selector = Expression.Property(param,
    typeof(Customer).GetProperty("ContactName"));
Expression pred = Expression.Lambda(selector, param);
//組建表達式樹:Select(c=>c.ContactName)
Expression expr = Expression.Call(typeof(Queryable), "Select",
    new Type[] { typeof(Customer), typeof(string) },
    Expression.Constant(custs), pred);
//使用表達式樹來生成動態查詢
IQueryable<string> query = db.Customers.AsQueryable()
    .Provider.CreateQuery<string>(expr);
//使用GetCommand方法獲取SQL語句
System.Data.Common.DbCommand cmd = db.GetCommand(query);
Console.WriteLine(cmd.CommandText);

生成的SQL語句為:

SELECT [t0].[ContactName] FROM [dbo].[Customers] AS [t0]

2.Where

下面一個例子是“搭建”Where用法來動態查詢城市在倫敦的顧客。

IQueryable<Customer> custs = db.Customers;
//創建一個參數c
ParameterExpression param = 
    Expression.Parameter(typeof(Customer), "c");
//c.City=="London"
Expression left = Expression.Property(param,
    typeof(Customer).GetProperty("City"));
Expression right = Expression.Constant("London");
Expression filter = Expression.Equal(left, right);

Expression pred = Expression.Lambda(filter, param);
//Where(c=>c.City=="London")
Expression expr = Expression.Call(typeof(Queryable), "Where",
    new Type[] { typeof(Customer) }, 
    Expression.Constant(custs), pred);
//生成動態查詢
IQueryable<Customer> query = db.Customers.AsQueryable()
    .Provider.CreateQuery<Customer>(expr);

生成的SQL語句為:

SELECT [t0].[CustomerID], [t0].[CompanyName], [t0].[ContactName], 
[t0].[ContactTitle], [t0].[Address], [t0].[City], [t0].[Region], 
[t0].[PostalCode], [t0].[Country], [t0].[Phone], [t0].[Fax]
FROM [dbo].[Customers] AS [t0] WHERE [t0].[City] = @p0
-- @p0: Input NVarChar (Size = 6; Prec = 0; Scale = 0) [London]
[第1頁][第2頁]
2
3
 
標簽:LINQ LINQ to SQL
 
 

文章列表

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()