標籤:
在進行資料查詢時,經常碰到需要動態構建查詢條件。使用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
LINQ to SQL 運行時動態構建查詢條件