有一种方法来准备动态查询和条件,并且还要用用它功能来构建它们的一部分。语法也是可读的,这可以解决问题的“简单”部分。有可能通过结合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