c# - 动态构建查询

标签 c# .net linq dynamic

您好,感谢您花时间回答我的问题。

在使用 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/

相关文章:

c# - MVC 脚手架和 EF 'One To Zero or One' 关系错误

c# - 为什么 Debug.WriteLine 的字符串格式不正确?

c# - ToLookup 是否强制立即执行序列

c# - 更新 ForEach 循环内的变量

c# - 如何找到最少数量的公共(public)集

c# - 本应增加 1 的分数却增加了 2

c# - ScriptManager.RegisterClientScriptIninclude 之后的 Javascript 对象 "is not defined"错误

c# - 清除 onMouseLeave JQuery 的大纲

c# - String.Concat(Object) 而不是 String.Concat(String) 的用途

c# - 将 IQueryable 列表转换为通用列表?