深度講解LINQ動態(tài)查詢
LINQ動態(tài)查詢運用的人很少,也許因為排斥,也許因為難以實現(xiàn),本文筆者就為大家介紹幾種LINQ動態(tài)查詢方法。
在LINQ動態(tài)查詢中,Lambda表達式是許多標準查詢運算符的基礎(chǔ),編譯器創(chuàng)建lambda表達式以捕獲基礎(chǔ)查詢方法(例如 Where、Select、Order By、Take While 以及其他方法)中定義的計算。表達式目錄樹用于針對數(shù)據(jù)源的結(jié)構(gòu)化查詢,這些數(shù)據(jù)源實現(xiàn)IQueryable
例如,LINQ to SQL 提供程序?qū)崿F(xiàn) IQueryable
表達式目錄樹在LINQ中用于表示分配給類型為Expression
System.Linq.Expressions命名空間提供用于手動生成表達式目錄樹的API。Expression類包含創(chuàng)建特定類型的表達式目錄樹節(jié)點的靜態(tài)工廠方法,例如,ParameterExpression(表示一個已命名的參數(shù)表達式)或 MethodCallExpression(表示一個方法調(diào)用)。編譯器生成的表達式目錄樹的根始終在類型Expression
下面幾個例子描述如何使用表達式目錄樹來創(chuàng)建LINQ動態(tài)查詢。
1.LINQ動態(tài)查詢之Select下面例子說明如何使用表達式樹依據(jù) IQueryable 數(shù)據(jù)源構(gòu)造一個動態(tài)查詢,查詢出每個顧客的ContactName,并用GetCommand方法獲取其生成SQL語句。
- //依據(jù)IQueryable數(shù)據(jù)源構(gòu)造一個查詢
- IQueryable
custs = db.Customers; - //組建一個表達式樹來創(chuàng)建一個參數(shù)
- ParameterExpression param = Expression.Parameter(typeof(Customer), "c");
- //組建表達式樹:
- c.ContactNameExpression 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);
- //使用表達式樹來生成動態(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動態(tài)查詢之Where下面一個例子是“搭建”Where用法來動態(tài)查詢城市在倫敦的顧客。
- IQueryable
custs = db.Customers; - //創(chuàng)建一個參數(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);
- //生成動態(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動態(tài)查詢之OrderBy本例既實現(xiàn)排序功能又實現(xiàn)了過濾功能。
- IQueryable
custs = db.Customers; - //創(chuàng)建一個參數(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));
- //生成動態(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動態(tài)查詢之Union下面的例子使用表達式樹動態(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);
- //生成動態(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動態(tài)查詢的一些方法。
【編輯推薦】