深度講解LINQ動(dòng)態(tài)查詢
LINQ動(dòng)態(tài)查詢運(yùn)用的人很少,也許因?yàn)榕懦?,也許因?yàn)殡y以實(shí)現(xiàn),本文筆者就為大家介紹幾種LINQ動(dòng)態(tài)查詢方法。
在LINQ動(dòng)態(tài)查詢中,Lambda表達(dá)式是許多標(biāo)準(zhǔn)查詢運(yùn)算符的基礎(chǔ),編譯器創(chuàng)建lambda表達(dá)式以捕獲基礎(chǔ)查詢方法(例如 Where、Select、Order By、Take While 以及其他方法)中定義的計(jì)算。表達(dá)式目錄樹用于針對(duì)數(shù)據(jù)源的結(jié)構(gòu)化查詢,這些數(shù)據(jù)源實(shí)現(xiàn)IQueryable
例如,LINQ to SQL 提供程序?qū)崿F(xiàn) IQueryable
表達(dá)式目錄樹在LINQ中用于表示分配給類型為Expression
System.Linq.Expressions命名空間提供用于手動(dòng)生成表達(dá)式目錄樹的API。Expression類包含創(chuàng)建特定類型的表達(dá)式目錄樹節(jié)點(diǎn)的靜態(tài)工廠方法,例如,ParameterExpression(表示一個(gè)已命名的參數(shù)表達(dá)式)或 MethodCallExpression(表示一個(gè)方法調(diào)用)。編譯器生成的表達(dá)式目錄樹的根始終在類型Expression
下面幾個(gè)例子描述如何使用表達(dá)式目錄樹來創(chuàng)建LINQ動(dòng)態(tài)查詢。
1.LINQ動(dòng)態(tài)查詢之Select下面例子說明如何使用表達(dá)式樹依據(jù) IQueryable 數(shù)據(jù)源構(gòu)造一個(gè)動(dòng)態(tài)查詢,查詢出每個(gè)顧客的ContactName,并用GetCommand方法獲取其生成SQL語句。
- //依據(jù)IQueryable數(shù)據(jù)源構(gòu)造一個(gè)查詢
 - IQueryable
 custs = db.Customers; - //組建一個(gè)表達(dá)式樹來創(chuàng)建一個(gè)參數(shù)
 - ParameterExpression param = Expression.Parameter(typeof(Customer), "c");
 - //組建表達(dá)式樹:
 - c.ContactNameExpression selector = Expression.Property(param,
 - typeof(Customer).GetProperty("ContactName"));
 - Expression pred = Expression.Lambda(selector, param);
 - //組建表達(dá)式樹:
 - Select(c=>c.ContactName)Expression expr =
 - Expression.Call(typeof(Queryable), "Select",
 - new Type[] { typeof(Customer), typeof(string) },
 - Expression.Constant(custs), pred);
 - //使用表達(dá)式樹來生成動(dòng)態(tài)查詢
 - 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.LINQ動(dòng)態(tài)查詢之Where下面一個(gè)例子是“搭建”Where用法來動(dòng)態(tài)查詢城市在倫敦的顧客。
- IQueryable
 custs = db.Customers; - //創(chuàng)建一個(gè)參數(shù)
 - cParameterExpression 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);
 - //生成動(dòng)態(tài)查詢IQueryable
 query = - db.Customers.AsQueryable() .Provider.CreateQuery
 (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]
 
3.LINQ動(dòng)態(tài)查詢之OrderBy本例既實(shí)現(xiàn)排序功能又實(shí)現(xiàn)了過濾功能。
- IQueryable
 custs = db.Customers; - //創(chuàng)建一個(gè)參數(shù)cParameterExpression 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")MethodCallExpression whereCallExpression =
 - Expression.Call( typeof(Queryable), "Where",
 - new Type[] { typeof(Customer) }, Expression.Constant(custs), pred);
 - OrderBy(ContactName =>
 - ContactName)MethodCallExpression orderByCallExpression =
 - Expression.Call( typeof(Queryable), "OrderBy",
 - new Type[] { typeof(Customer), typeof(string) },
 - whereCallExpression,
 - Expression.Lambda(Expression.Property (param, "ContactName"), param));
 - //生成動(dòng)態(tài)查詢
 - IQueryable
 query = - db.Customers.AsQueryable().Provider.CreateQuery
 - (orderByCallExpression);
 
生成的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] =
 - @p0ORDER BY [t0].[ContactName]-- @p0:
 - Input NVarChar (Size = 6; Prec = 0; Scale = 0) [London]
 
4.LINQ動(dòng)態(tài)查詢之Union下面的例子使用表達(dá)式樹動(dòng)態(tài)查詢顧客和雇員同在的城市。
- //e.CityIQueryable
 custs = db.Customers; - ParameterExpression param1 = Expression.Parameter(typeof(Customer), "e");
 - Expression left1 = Expression.Property(param1,
 - typeof(Customer).GetProperty("City"));
 - Expression pred1 = Expression.Lambda(left1, param1);
 - c.CityIQueryable
 employees = - db.Employees;ParameterExpression param2 =
 - Expression.Parameter(typeof(Employee), "c");
 - Expression left2 = Expression.Property(param2,
 - typeof(Employee).GetProperty("City"));
 - Expression pred2 = Expression.Lambda(left2, param2);
 - Select(e=>e.City)Expression expr1 =
 - Expression.Call(typeof(Queryable), "Select",
 - new Type[] { typeof(Customer), typeof(string) },
 - Expression.Constant(custs), pred1);
 - Select(c=>c.City)Expression expr2 =
 - Expression.Call(typeof(Queryable), "Select",
 - new Type[] { typeof(Employee), typeof(string) },
 - Expression.Constant(employees), pred2);
 - //生成動(dòng)態(tài)查詢
 - IQueryable<string> q1 =
 - db.Customers.AsQueryable().Provider.CreateQuery<string>(expr1);
 - IQueryable<string> q2 =
 - db.Employees.AsQueryable().Provider.CreateQuery<string>(expr2);
 - //并集
 - var q3 = q1.Union(q2);
 
生成的SQL語句為:
- SELECT [t2].[City]
 - FROM
 - ( SELECT [t0].[City] FROM [dbo].[Customers] AS [t0]
 - UNION SELECT [t1].[City] FROM [dbo].[Employees] AS [t1] )
 - AS [t2]
 
以上就是關(guān)于LINQ動(dòng)態(tài)查詢的一些方法。
【編輯推薦】















 
 
 
 
 
 
 