LINQ PredicateBuilder有条件的AND,OR和NOT过滤器 [英] Linq PredicateBuilder with conditional AND, OR and NOT filters

查看:3632
本文介绍了LINQ PredicateBuilder有条件的AND,OR和NOT过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们必须使用LINQ to SQL的一个项目,为此我需要重写几个搜索页面,让客户选择他们是否愿意执行的的或的的搜索。

We have a project using LINQ to SQL, for which I need to rewrite a couple of search pages to allow the client to select whether they wish to perform an and or an or search.

不过,我觉得有关重做的LINQ查询使用的 PredicateBuilder 并得到了这方面的工作非常好,我认为。我有效地有一个类包含我的谓词,例如:

I though about redoing the LINQ queries using PredicateBuilder and have got this working pretty well I think. I effectively have a class containing my predicates, e.g.:

internal static Expression<Func<Job, bool>> Description(string term)
{
    return p => p.Description.Contains(term);
}

要执行搜索我这样做(为简洁起见省略了一些代码)

To perform the search i'm doing this (some code omitted for brevity):

public Expression<Func<Job, bool>> ToLinqExpression()
{
    var predicates = new List<Expression<Func<Job, bool>>>();
    // build up predicates here

    if (SearchType == SearchType.And)
    {
        query = PredicateBuilder.True<Job>();
    }
    else
    {
        query = PredicateBuilder.False<Job>();
    }

    foreach (var predicate in predicates)
    {
        if (SearchType == SearchType.And)
        {
            query = query.And(predicate);
        }
        else
        {
            query = query.Or(predicate);
        }
    }
    return query;
}



而我与此相当快乐,我有两个问题:

While i'm reasonably happy with this, I have two concerns:


  1. 的如果评价一个检索类别属性/ else块感觉他们可能是一个潜在的代码味道。

  2. 客户端现在坚持能够执行'而不是'/'或不'搜索。

要解决2点,我想我可以通过简单地重写我的表情,这样做如:

To address point 2, I think I could do this by simply rewriting my expressions, e.g.:

internal static Expression<Func<Job, bool>> Description(string term, bool invert)
{
    if (invert)
    {
        return p => !p.Description.Contains(term);
    }
    else
    {
        return p => p.Description.Contains(term);
    }
}



不过这种感觉就像有点杂牌的,这通常意味着有一个更好的解决方案在那里。谁能推荐如何可以改善?我知道动态LINQ,但我真的不希望失去LINQ的强类型。

However this feels like a bit of a kludge, which usually means there's a better solution out there. Can anyone recommend how this could be improved? I'm aware of dynamic LINQ, but I don't really want to lose LINQ's strong typing.

推荐答案

如果您正在寻找少线路可以代替的if / else三元运算符:

If you are looking for less lines you can replace the if/else with ternary operator:

query = SearchType == SearchType.And ? PredicateBuilder.True<Job>() : PredicateBuilder.False<Job>();

   foreach (var predicate in predicates)
   {
        query = SearchType == SearchType.And ? query.And(predicate) : query.Or(predicate);
   }

'而不是'/'或不部分 运营商应该做的伎俩

for the 'and not' / 'or not' part the ! operator should do the trick.

PD!: 你测试的foreach 部分正确设置谓词?据我记得你正在建设将在稍后的时间点执行的表情,所以你可能有一个文字引用只是在最后一次迭代的最后一组断言,这就是为什么你必须使用一个临时变量保存每个迭代的值。

PD: Did you test the foreach part is correctly setting the predicates?, as far as i remember you are building the expression that will be executed at later point in time, so you may have a literal reference just to the last set predicate in the final iteration, and that's why you must use a temp variable to save the value of each iteration.

修改
如果你想否定一个表达式程序,这是一个很微妙的,你可以尝试这样的:

If you want to negate a expression programmatic, that's a tricky one, you can try something like:

internal static Expression<Func<Job, bool>> Description(string term, bool invert)
        {
           return NegateExp<Func<Job, bool>>(p => p.Description.Contains(term), invert);
        }



而NegateExp方法是这样的:

And the NegateExp method will be something like:

public static Expression<TDelegate> NegateExp<TDelegate>(Expression<TDelegate> expression, bool inverse)
        {
            if (inverse)
            {
                return Expression.Lambda<TDelegate>(Expression.Not(expression.Body), expression.Parameters);
            }
            return expression;
        }

您可以看看这个问题,更多的例子的http://stackoverflow.com/questions/2166591/is-there-any-way-to -negate-A-谓词

You can take a look at this question for more examples http://stackoverflow.com/questions/2166591/is-there-any-way-to-negate-a-predicate

这篇关于LINQ PredicateBuilder有条件的AND,OR和NOT过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆