熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

LINQ to SQL語句之動態查詢

2013-11-13 10:30:59  來源: .NET編程 

  LINQ to SQL語句之動態查詢
高級特性
本文介紹LINQ的高級特性其包括大家都關心的動態查詢的用法另外簡單提下ID標識這個知識

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

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

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

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

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

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

  //依據IQueryable數據源構造一個查詢IQueryable<Customer> custs = dbCustomers;//組建一個表達式樹來創建一個參數ParameterExpressionparam =ExpressionParameter(typeof(Customer)c);//組建表達式樹:cContactNameExpressionselector =ExpressionProperty(paramtypeof(Customer)GetProperty(ContactName));Expressionpred =ExpressionLambda(selector param);//組建表達式樹:Select(c=>cContactName)Expressionexpr =ExpressionCall(typeof(Queryable)SelectnewType[] {typeof(Customer)typeof(string) }ExpressionConstant(custs) pred);//使用表達式樹來生成動態查詢IQueryable<string> query = dbCustomersAsQueryable()
    ProviderCreateQuery<string>(expr);//使用GetCommand方法獲取SQL語句SystemDataCommonDbCommandcmd = dbGetCommand(query);ConsoleWriteLine(cmdCommandText);
生成的SQL語句為

  SELECT[t][ContactName]FROM[dbo][Customers]AS[t]
Where
下面一個例子是搭建Where用法來動態查詢城市在倫敦的顧客

  IQueryable<Customer> custs = dbCustomers;//創建一個參數cParameterExpressionparam =ExpressionParameter(typeof(Customer)c);//cCity==LondonExpressionleft =ExpressionProperty(paramtypeof(Customer)GetProperty(City));Expressionright =ExpressionConstant(London);Expressionfilter =ExpressionEqual(left right);Expressionpred =ExpressionLambda(filter param);//Where(c=>cCity==London)Expressionexpr =ExpressionCall(typeof(Queryable)WherenewType[] {typeof(Customer) }ExpressionConstant(custs) pred);//生成動態查詢IQueryable<Customer> query = dbCustomersAsQueryable()
    ProviderCreateQuery<Customer>(expr);
生成的SQL語句為

  SELECT[t][CustomerID] [t][CompanyName] [t][ContactName]
[t][ContactTitle] [t][Address] [t][City] [t][Region]
[t][PostalCode] [t][Country] [t][Phone] [t][Fax]FROM[dbo][Customers]AS[t]WHERE[t][City] = @p @p: Input NVarChar (Size = ; Prec = ; Scale = ) [London]
OrderBy
本例既實現排序功能又實現了過濾功能

  IQueryable<Customer> custs = dbCustomers;//創建一個參數cParameterExpressionparam =ExpressionParameter(typeof(Customer)c);//cCity==LondonExpressionleft =ExpressionProperty(paramtypeof(Customer)GetProperty(City));Expressionright =ExpressionConstant(London);Expressionfilter =ExpressionEqual(left right);Expressionpred =ExpressionLambda(filter param);//Where(c=>cCity==London)MethodCallExpressionwhereCallExpression =ExpressionCall(typeof(Queryable)WherenewType[] {typeof(Customer) }ExpressionConstant(custs) pred);//OrderBy(ContactName => ContactName)MethodCallExpressionorderByCallExpression =ExpressionCall(typeof(Queryable)OrderBynewType[] {typeof(Customer)typeof(string) }
    whereCallExpressionExpressionLambda(ExpressionProperty
    (paramContactName) param));//生成動態查詢IQueryable<Customer> query = dbCustomersAsQueryable()
    ProviderCreateQuery<Customer>(orderByCallExpression);
下面一張截圖顯示了怎麼動態生成動態查詢的過程

  生成的SQL語句為

  SELECT[t][CustomerID] [t][CompanyName] [t][ContactName]
[t][ContactTitle] [t][Address] [t][City] [t][Region]
[t][PostalCode] [t][Country] [t][Phone] [t][Fax]FROM[dbo][Customers]AS[t]WHERE[t][City] = @pORDER BY[t][ContactName] @p: Input NVarChar (Size = ; Prec = ; Scale = ) [London]
Union
下面的例子使用表達式樹動態查詢顧客和雇員同在的城市

  //eCityIQueryable<Customer> custs = dbCustomers;ParameterExpressionparam =ExpressionParameter(typeof(Customer)e);Expressionleft =ExpressionProperty(paramtypeof(Customer)GetProperty(City));Expressionpred =ExpressionLambda(left param);//cCityIQueryable<Employee> employees = dbEmployees;ParameterExpressionparam =ExpressionParameter(typeof(Employee)c);Expressionleft =ExpressionProperty(paramtypeof(Employee)GetProperty(City));Expressionpred =ExpressionLambda(left param);//Select(e=>eCity)Expressionexpr =ExpressionCall(typeof(Queryable)SelectnewType[] {typeof(Customer)typeof(string) }ExpressionConstant(custs) pred);//Select(c=>cCity)Expressionexpr =ExpressionCall(typeof(Queryable)SelectnewType[] {typeof(Employee)typeof(string) }ExpressionConstant(employees) pred);//生成動態查詢IQueryable<string> q = dbCustomersAsQueryable()
    ProviderCreateQuery<string>(expr);IQueryable<string> q = dbEmployeesAsQueryable()
    ProviderCreateQuery<string>(expr);//並集varq = qUnion(q);
生成的SQL語句為

  SELECT[t][City]FROM(SELECT[t][City]FROM[dbo][Customers]AS[t]UNION
    SELECT[t][City]FROM[dbo][Employees]AS[t]
    )AS[t]
ID標識
在前面這一點沒有說到在這裡作為高級特性單獨說下ID標識

  這個例子說明我們存儲一條新的記錄時候ContactID作為主鍵標識

  系統自動分配標識種子為所以每次自動加一

  //ContactID是主鍵ID插入一條數據系統自動分配IDContactcon =newContact()
{
    CompanyName =New Era
    Phone =()};
dbContactsInsertOnSubmit(con);
dbSubmitChanges();


From:http://tw.wingwit.com/Article/program/net/201311/13872.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.