【问题标题】:Where or (not and) with list of expressions c#where or (not and) 与表达式列表 c#
【发布时间】:2013-04-29 08:09:20
【问题描述】:

我得到以下代码

public class Personnel {
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int OrganizationalUnitId { get; set; }
    public int RoleId { get; set; }
}

private List<Expression<Func<Personnel, bool>>> personnelFilter;

public void AddFilter(Expression<Func<Personnel, bool>> filter)
{
    this.personnelFilter.Add(filter);
}

public IEnumerable<Personnel> GetResult()
{
    IQueryable<Personnel> personnel = Store.Instance.Query<Personnel>();
    foreach(var filter in this.personnelFilter)
    {
        personnel = personnel.Where(filter);
    }

    return personnel;
}

它现在使用 AND,因为它会将 Where 子句附加到已过滤的查询中。但我不想将其添加为 AND,而是添加为 OR。

假设我添加了过滤器:

model.AddFilter(a => a.FirstName == "Test")
model.AddFilter(a => a.FirstName == "More")

// Or adding something stupid like:
model.AddFilter(a => a.OrganizationalUnit == 1)
model.AddFilter(a => a.OrganizationalUnit == 1)

我想要以下查询:

WHERE Firstname == "Test" || Firstname == "More"

不做:

model.AddFilter(a => a.FirstName == "Test" || a.FirstName == "More")

这可能吗?换句话说,我得到了一个带有表达式的列表,我想在 where 子句中对它们进行 OR 操作而不是 AND,但我找不到让它工作的方法。有什么想法吗?

【问题讨论】:

  • 什么是Expression&lt;Personnel, bool&gt;?根据 MSDN,它不存在 (msdn.microsoft.com/en-us/library/bb506649.aspx)。我想这一定是我Func&lt;Personnel, bool&gt;?
  • @Martin Mulder,纠正了它,我动态创建了一个示例。
  • 您说您尝试过 Expression.Or 但它失败了。你能说出失败的原因吗?
  • 缺乏知识,请看下面的答案,它的类型错误,但您可以轻松地将其转换为 Func

标签: c# lambda filtering where iqueryable


【解决方案1】:

试试这样的:(代码不起作用)

这似乎是一种倒退,但只是反转逻辑:A || B 等于 !(!A && !B)。 except() 是 Where() 的否定版本,所以你应该没问题。


编辑:我已经工作了,看来你必须像这样正确组合它们:

public static Expression<Func<T, bool>> Combine_Or<T>(
    Expression<Func<T, bool>> expr1,
    Expression<Func<T, bool>> expr2)
{
    var invokedExpr = Expression.Invoke(expr2, expr1.Parameters.Cast<Expression>());
    return Expression.Lambda<Func<T, bool>>
          (Expression.OrElse(expr1.Body, invokedExpr), expr1.Parameters);
}

基本上取自这里:Lambda expressions and how to combine them?

我的完整测试代码:http://pastebin.com/cLXi77pf

【讨论】:

  • 数据库(引擎)应该简化表达式并且 !(!A && !B) 应该变成 A || B,所以我想这是一个很好的解决方案:)
  • ... 除了只接受 IENumerable,没有表达式。
  • 我的编辑,您需要修改表达式树以正确组合 lambda。
  • 工作太棒了!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-14
  • 1970-01-01
  • 1970-01-01
  • 2014-05-13
相关资源
最近更新 更多