gpt4 book ai didi

c# - 具有条件 AND、OR 和 NOT 过滤器的 Linq PredicateBuilder

转载 作者:太空狗 更新时间:2023-10-29 22:55:42 25 4
gpt4 key购买 nike

我们有一个使用 LINQ to SQL 的项目,为此我需要重写几个搜索页面以允许客户选择他们是否希望执行 andor 搜索。

我虽然关于使用 PredicateBuilder 重做 LINQ 查询我认为这已经很好地工作了。我实际上有一个包含我的谓词的类,例如:

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

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

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;
}

虽然我对此相当满意,但我有两个担忧:

  1. 评估 SearchType 属性的 if/else block 感觉它们可能是一种潜在的代码味道。
  2. 客户现在坚持要能够执行“and not”/“or not”搜索。

为了解决第 2 点,我想我可以通过简单地重写我的表达式来做到这一点,例如:

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 的强类型。

最佳答案

如果您正在寻找更少的行,您可以将 if/else 替换为三元运算符:

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);
}

对于 'and not'/'or not' 部分,! 运算符应该可以解决问题。

PD: 您是否测试过 foreach 部分是否正确设置了谓词?据我记得,您正在构建将在稍后执行的表达式time,因此您可能只对最后一次迭代中的最后一个 set 谓词有一个文字引用,这就是为什么您必须使用临时变量来保存每次迭代的值。

编辑:如果你想否定一个表达式编程,这是一个棘手的,你可以尝试这样的事情:

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

NegateExp 方法类似于:

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;
}

您可以查看此问题以获取更多示例 Is there any way to negate a Predicate?

关于c# - 具有条件 AND、OR 和 NOT 过滤器的 Linq PredicateBuilder,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3043995/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com