c# - 如何在 linq 中多次调用 .Where() 方法来表现得像 OR (||)

标签 c# .net linq linq-to-objects


我正在尝试创建一个类,允许我在运行时使用 .Where() 方法配置 LINQ 查询,在完成我的类(class)后,虽然测试结果不符合我的预期,但我遇到了问题并解决了我需要的问题调用多个 .Where() 方法时间,它应该像 OR ||不像 AND &&
示例:

class Program
{

    private static string WhereTest()
    {
        string result = "";

        // List
        string[] lst = { "Sa", "Su", "Mo", "Tu", "We", "Th", "Fr" };

        // test 1
        var q1 = from l in lst
                 where l.StartsWith("S") && l.EndsWith("u")
                 select l;
        result = "1st query count: " + q1.Count() 
            + "\n----------------- \nItems: \n------- \n";
        foreach (var item in q1.ToList())
        {
            result += item + "\n";
        }
        result += "\n";
        result += "\n";

        // test 2
        var q2 = from l in lst
                 where l.StartsWith("S") || l.EndsWith("u")
                 select l;
        result += "2nd query count: " + q2.Count() 
            + "\n----------------- \nItems: \n------- \n";
        foreach (var item in q2.ToList())
        {
            result += item + "\n";
        }
        result += "\n";
        result += "\n";

        // test 3
        var q3 = from l in lst
                 select l;
        if (true)
            q3 = q3.Where(l => l.StartsWith("S"));
        if (true)
            q3 = q3.Where(l => l.EndsWith("u"));

        result += "3rd query count: " + q3.Count() 
            + "\n----------------- \nItems: \n------- \n";
        foreach (var item in q3.ToList())
        {
            result += item + "\n";
        }
        result += "\n";
        result += "\n";


        return result;
    }
    static void Main(string[] args)
    {
        Console.WriteLine(WhereTest());
    }
}


结果:

            1st query count: 1
            -----------------
            Items:
            -------
            Su


            2nd query count: 3
            -----------------
            Items:
            -------
            Sa
            Su
            Tu


            3rd query count: 1
            -----------------
            Items:
            -------
            Su

在我的示例中,q3 返回与 q1 相同的结果
所以我需要知道我是否可以让 q3 返回与 q2 相同的结果。
问候

最佳答案

对于 LINQ to SQL 或其他基于可查询的提供程序,PredicateBuilder是解决方案。它不允许您多次调用 Where,但可以让您使用多次调用动态创建谓词。

对于 LINQ to Objects,您可以使用委托(delegate)而不是表达式树创建您自己的 PredicateBuilder 等效项,as shown in this answer .为了使这个答案独立完成,这里再次使用相同的代码:

public static class DelegatePredicateBuilder
{
  public static Func<T, bool> True<T>()  { return f => true;  }
  public static Func<T, bool> False<T>() { return f => false; }

  public static Func<T, bool> Or<T>(this Func<T, bool> expr1,
                                     Func<T, bool> expr2)
  {
      return t => expr1(t) || expr2(t);
  }

  public static Func<T, bool> And<T>(this Func<T, bool> expr1,
                                     Func<T, bool> expr2)
  {
      return t => expr1(t) && expr2(t);
  }
}

所以你会使用类似的东西:

var predicate = DelegatePredicateBuilder.False<string>();

if (someCondition)
{
    predicate = predicate.Or(l => l.StartsWith("S"));
}

if (someCondition)
{
    predicate = predicate.Or(l => l.EndsWith("u"));
}

query = query.Where(predicate);

关于c# - 如何在 linq 中多次调用 .Where() 方法来表现得像 OR (||),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8634693/

相关文章:

c# - .Net 中 LINQ 和 Lambda 表达式的效率和性能如何?

c# - 如何通过 SSIS 中的主包在 TFS 上运行包?

c# - FluentAssertions WhenType 是 double.NaN

c# - 绑定(bind)复选框命令

python - 在 Python 中使用 .NET dll

c# - 如何在 C# 中的 lambda 表达式中查找数组中元素的索引

c# - 在 Entity Framework 对象中使用外部对象

c# - .Net 在不同的文件中连续写入数据到磁盘

C# 'SerialPort' 不包含采用 6 个参数的构造函数

c# - 在 LINQ group by procedure 之后访问 List<T> 中保存的对象属性