首页 > 代码库 > LINQ to SQL 运行时动态构建查询条件

LINQ to SQL 运行时动态构建查询条件

在进行数据查询时,经常碰到需要动态构建查询条件。使用LINQ实现这个需求可能会比以前拼接SQL语句更麻烦一些。本文介绍了3种运行时动态构建查询条件的方法。 本文中的例子最终实现的都是同一个功能,从Northwind数据库Customers表中搜索出CompanyName列带有keywords中任意元素的项。keywords是个字符串数组,该数组长度在编译时是不确定的。思路及方法说明写在代码注释中。

1.表达式树

1   public static IEnumerable<Customers> GetCustomersFunc1(string[] keywords)  
2     {  
3         DataClassesDataContext dc = new DataClassesDataContext();  

5         //创建一个静态类型为Customers的参数表达式  
6         ParameterExpression c = Expression.Parameter(typeof(Customers), "c");  
7   
8         //创建一个恒等于false的表达式,用于与下面的表达式取并集  
9    Expression condition = Expression.Constant(false); 
10         foreach (string keyword in keywords) 
11          { 
12             //该表达式用于判断一个Customers类的CompanyName属性的值是否包含了关键字keyword 
13            Expression con = Expression.Call(   
14   Expression.Property(c, typeof(Customers).GetProperty("CompanyName")), 
15                typeof(string).GetMethod("Contains", new Type[]  { typeof(string) }), 
16    Expression.Constant(keyword)); 
17  
18             //与之前的condition表达式进行逻辑或运算。 
19             //如果要查找的项需要包含keywords中的所有关键字,则可使用Expression.And(con, condition)20             //并且将Expression condition = Expression.Constant(false); 
21             //改成Expression condition = Expression.Constant(true); 
22             condition = Expression.Or(con, condition);   
23         } 
24  
25         //创建一个以一个Customers类作为参数并返回bool类型的委托 
26   Expression<Func<Customers, bool>> end = Expression.Lambda<Func<Customers, bool>>(condition, new ParameterExpression[]  { c }); 
27  
28         //使用刚才构建的条件进行查询 
29         var result = dc.Customers.Where(end); 
30         return result; 
31     } 
32

2.使用System.Linq.Dynamic

public static IEnumerable<Customers> GetCustomersFunc2(string[] keywords)  
2     { 
3         //需要引用System.Linq.Dynamic。Dynamic.cs文件可在LinqSamples中找到  
4   
5        DataClassesDataContext dc = new DataClassesDataContext();  
6         string queryString = "";  
7         foreach (string keyword in keywords) 
8         {  
9             //原形为(c=>c.CompanyName.Contains(keyword1)) || (c=>c.CompanyName.Contains(keyword2)) ||   
10             queryString += "CompanyName.Contains(\"" + keyword + "\") or "; 
11         } 
12  
13         //与false进行逻辑或运算,为了避免queryString中最后的or出现语法错误 
14         queryString += "1=0"; 
15         return dc.Customers.Where(queryString); 
16     } 
17

3.披着Linq的外衣拼接SQL语句

1     public static IEnumerable<Customers> GetCustomersFunc3(string[] keywords)  
2      {  
3         //这个方法其实是伪Linq,核心还是在拼接SQL语句,所以就不多解释了  
4         DataClassesDataContext dc = new DataClassesDataContext();  
5         string sqlQuery = "SELECT [CustomerID], [CompanyName], [ContactName], [ContactTitle], [Address], ";  
6         sqlQuery += "[City], [Region], [PostalCode],[Country], [Phone], [Fax] FROM [dbo].[Customers]  WHERE ";  
7         foreach (string keyword in keywords) 
8          {  
9             sqlQuery += "([CompanyName] LIKE ‘%" + keyword + "%‘ ) OR "; 
10         } 
11         sqlQuery += "(1=0)"; 
12         return dc.ExecuteQuery<Customers>(sqlQuery); 
13     } 
14  
15

LINQ to SQL 运行时动态构建查询条件