有一種方法來準備動態查詢和條件,並且還要用用它功能來構建它們的一部分。語法也是可讀的,這可以解決問題的「簡單」部分。有可能通過結合Linq表達式。有幾篇關於如何完成的文章,但我想我想出了一個新的方法。至少我沒有在網上找到它。
要繼續,您需要一個包含3個簡單功能的庫。他們使用System.Linq.Expressions.ExpressionVisitor
來動態修改表達式。關鍵特性是將表達式中的參數統一起來,以便使具有相同名稱的兩個參數相同(UnifyParametersByName
)。其餘部分將用給定表達式(ReplacePar
)和輔助方法(NewExpr
)替換命名參數。該圖書館提供github上的MIT許可證:LinqExprHelper,但您可以自行快速編寫一些內容。
首先定義一些方法,稍後可用於創建動態查詢。
public class Store
{
...
public static Expression<Func<Store, bool>>
SafeSearchName(string sWhat)
{
return LinqExprHelper.NewExpr(
(Store s) => s.Name != null && s.Name.ToLower().Contains(sWhat)
);
}
public static Expression<Func<Store, bool>>
SafeSearchDesc(string sWhat)
{
return LinqExprHelper.NewExpr(
(Store s) => s.Description != null && s.Description.ToLower().Contains(sWhat)
);
}
}
然後你以這種方式查詢:
// Define a master condition, using named parameters.
var masterExpr = LinqExprHelper.NewExpr(
(Store s, bool bSearchName, bool bSearchDesc)
=> (bSearchName && bSearchDesc));
// Replace stub parameters with some real conditions.
var combExpr = masterExpr
.ReplacePar("bSearchName", Store.SafeSearchName("b").Body)
.ReplacePar("bSearchDesc", Store.SafeSearchDesc("p").Body);
// Sometimes you may skip a condition using this syntax:
//.ReplacePar("bSearchDesc", Expression.Constant(true));
// It's interesting to see how the final expression looks like.
Console.WriteLine("expr: " + combExpr);
// Execute the query using combined expression.
db.Stores
.Where((Expression<Func<Store, bool>>)combExpr)
.ToList().ForEach(i => { Console.WriteLine(i.Name + ", " + i.Description); });
我沒有在生產中使用這個還沒有,但一些簡單的測試都通過了。我沒有看到用這種方式組合查詢有任何限制。如果我們需要更多的參數,我們可以附加額外的組合級別。這種方法的優點是可以使用內聯的lambda表達式,這些表達式非常適合閱讀,還可以使用動態表達式創建和組合,這非常有用。
畢竟它「簡單」嗎?如果您認爲Linq的方法語法很簡單,那麼這幾乎就是這麼簡單。它不允許你創建自定義的Linq函數,但是可以提供類似的功能。
數據庫上的排序規則類型是什麼? – Brannon