【问题标题】:Linq chaining where clauses as an Or instead of And [duplicate]Linq将where子句链接为Or而不是And [重复]
【发布时间】:2019-10-31 10:07:23
【问题描述】:

此代码中有多个链接的 where 子句。我需要将下面代码 sn-p 中最后一个 where 子句的逻辑更改为“OR”而不是“AND”。 这背后的逻辑是,我希望所有交易都在传入的日期范围之间,以及所有交易状态为 TransactionStatus.Outstanding 的交易。目前逻辑是在做一个 AND 所以它只给了我两者之间的交集。

我在 Stack Overflow 中看到许多其他帖子解决了我正在处理的场景,但似乎没有一个对我有帮助。

非常感谢任何有关代码语法的指导!

IQueryable<Transaction> transactions = 
    _db.Transactions
        .Include(t => t.DepositSource)
        .Include(t => t.WithdrawalSource)
        .Include(t => t.ReconciliationReport)
        .Where(t => t.FundId == fundId);

if (criteria.UseClearedDate)
{
    transactions = transactions
        .Where(t => t.ReconciliationReport != null 
                    && (t.ReconciliationReport.DateCreated.Date >= criteria.StartDate.Date
                    && t.ReconciliationReport.DateCreated.Date <= criteria.EndDate.Date));
}
else
{
    transactions = transactions
        .Where(t => t.Date.Date >= criteria.StartDate.Date
                    && t.Date.Date <= criteria.EndDate.Date);
}
transactions = transactions
    .Where(t => (criteria.Statuses.Contains(t.ReconciliationId == null 
                ? t.IsVoided 
                    ? TransactionStatus.Void 
                    : TransactionStatus.Outstanding 
                : TransactionStatus.Cleared))
                && criteria.Sources.Contains(t.TransactionSource) 
                && criteria.Types.Contains(t.TransactionType));

【问题讨论】:

  • LinqKit 库很好地抽象了这一点。看看吧。
  • @JSteward 你能告诉我如何在我的代码 sn-p 中实现 PredicateBuilder 吗?非常感谢!
  • 如果您在应用 PredicateBuilder 时遇到困难,您可以通过一个简单的 UNION 来解决您的 if/else 的结果,并使用一个新查询将您的最终 Where 子句应用于原始交易集。

标签: c# linq


【解决方案1】:

没有办法“链接”其中的子句让它们充当or。第一个 Where 子句将过滤掉与其谓词不匹配的任何内容,因此第二个过滤器无法知道与第一个过滤器不匹配的那些甚至存在。

您可以按照重复问题中的建议使用第三方PredicateBuilder,也可以使用为您完成此操作的自定义扩展方法:

类似的东西(未经测试):

public IQueryable<T> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource,Boolean>> pred1, Expression<Func<TSource,Boolean>> pred2)
{
    return source.Where(t => pred1(t) || pred2(t));
}

【讨论】:

  • where 子句倒序怎么办?第一个 where 子句将包括第二个 where 子句可能的所有记录。第二个 where 子句将充当 OR,这样它将返回第一个 where 子句中的所有内容以及也满足第二个 where 子句要求的记录。
  • 这仍然是 AND,而不是 OR。顺序无关紧要。假设一个项目匹配第二个子句但不匹配第一个子句?
  • 您能告诉我如何使用我的代码实现您的解决方案吗?非常感谢!
猜你喜欢
  • 2021-02-02
  • 1970-01-01
  • 1970-01-01
  • 2017-12-07
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 2010-10-30
  • 1970-01-01
相关资源
最近更新 更多