在進行數據查詢時,經常碰到需要動態構建查詢條件。使用LINQ實現這個需求可能會比以前拼接SQL語 句更麻煩一些。本文介紹了3種運行時動態構建查詢條件的方法。本文中的例子最終實現的都是同一個功 能,從Northwind數據庫Customers表中搜索出CompanyName列帶有keywords中任意元素的項。keywords是 個字符串數組,該數組長度在編譯時是不確定的。思路及方法說明寫在代碼注釋中。
1.表達式樹
1 public static IEnumerable<Customers> GetCustomersFunc1(string[] keywords)
2 {
3 DataClassesDataContext dc = new DataClassesDataContext();
4
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
1 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