您好,感谢您花时间回答我的问题。
在使用 Java 一年半之后,我决定切换回 .NET。我必须说我在 VS2012 中有宾至如归的感觉。
在使用 Java 时,我遇到了一个可以轻松创建动态查询的休眠实现。
假设我有一个包含 5 个字段的表单,其中只有一个字段必须被填充,以便我过滤结果。
有没有一种方法可以在 C# 中执行以下操作:
if(txtMunicipality.text.length > 0){
(x => x.municipality == txtMunicipality.text)
}
if(chkboxIsFinished){
(x => x.isfinished == true)
}
等..
因此,我检查每个字段,如果值已被填充,则将该条件添加到查询中。完成检查后,我执行查询。有没有办法在 C# 中执行此操作?
最佳答案
最简单的方法是组合两个查询,即
IQueryable<Foo> query = ... // or possibly IEnumerable<Foo>
if(!string.IsNullOrEmpty(txtMunicipality.text)) {
query = query.Where(x => x.municipality == txtMunicipality.text);
}
if(chkboxIsFinished) {
query = query.Where(x.isfinished);
}
您也可以直接组合表达式树和委托(delegate);如果您需要,请指出您拥有的是:表达式树还是委托(delegate)。
编辑:下面是您将如何编写表达式而不是查询:
static class Program
{
static void Main()
{
Expression<Func<int, bool>> exp1 = x => x > 4;
Expression<Func<int, bool>> exp2 = x => x < 10;
Expression<Func<int, bool>> exp3 = x => x == 36;
var combined = (exp1.AndAlso(exp2)).OrElse(exp3);
// ^^^ equiv to x => (x > 4 && x < 10) || x == 36
}
static Expression<Func<T, bool>> OrElse<T>(this Expression<Func<T, bool>> x, Expression<Func<T, bool>> y)
{ // trivial cases
if (x == null) return y;
if (y == null) return x;
// rewrite using the parameter from x throughout
return Expression.Lambda<Func<T, bool>>(
Expression.OrElse(
x.Body,
SwapVisitor.Replace(y.Body, y.Parameters[0], x.Parameters[0])
), x.Parameters);
}
static Expression<Func<T, bool>> AndAlso<T>(this Expression<Func<T, bool>> x, Expression<Func<T, bool>> y)
{ // trivial cases
if (x == null) return y;
if (y == null) return x;
// rewrite using the parameter from x throughout
return Expression.Lambda<Func<T, bool>>(
Expression.AndAlso(
x.Body,
SwapVisitor.Replace(y.Body, y.Parameters[0], x.Parameters[0])
), x.Parameters);
}
class SwapVisitor : ExpressionVisitor
{
public static Expression Replace(Expression body, Expression from, Expression to)
{
return new SwapVisitor(from, to).Visit(body);
}
private readonly Expression from, to;
private SwapVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
return node == from ? to : base.Visit(node);
}
}
}
关于c# - 动态构建查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13721002/