LINQ:在运行时构建一个where子句以包含OR(||)?

时间:2011-02-20 11:07:24

标签: linq linq-to-sql dynamic-linq

我需要在运行时构建一个where子句,但我需要使用where子句进行OR。这可能吗。让我解释..

这里我的代码...,基本上“过滤器”是一个枚举按位,儿子因此过滤器可能等于下面的多于1个。因此我需要建立where子句......

如果我单独执行wheres而不是想象我是否先进行未经测试,并且它返回0条记录,这意味着我无法在Tested上执行where,因为它现在为0条记录。

我将在下面放一些伪代码:-)

        string myWhere = "";

        if ((filter & Filters.Tested) == Filters.Tested)
        {
             if (myWhere != "" ) myWhere =myWhere + "||";
             myWhere = myWhere " Status == "Tested";

        }

        if ((filter & Filters.Untested) == Filters.Untested)
        {
             if (myWhere != "" ) myWhere =myWhere + "||";
             myWhere = myWhere " Status == "Untested";
        }

        if ((filter & Filters.Failed) == Filters.Failed)
        {
             if (myWhere != "" ) myWhere =myWhere + "||";
             myWhere = myWhere " Status == "Failed";
        }

        // dataApplications = a List of items that include Tested,Failed and Untested.

        // dataApplciation.Where ( myWhere) ---  Confused here!  

这可能吗......

我不想包含大量的“IF”,因为有很多组合,即没有过滤器,过滤器=仅测试过滤器,过滤器=未测试和测试......以及更多

任何想法都非常感激

由于

3 个答案:

答案 0 :(得分:4)

如果你有这个:

IEnumerable<MyType> res = from p in myquery select p;

您可以定义

var conditions = new List<Func<MyType, bool>>();

conditions.Add(p => p.PropertyOne == 1);
conditions.Add(p => p.PropertyTwo == 2);

res = res.Where(p => conditions.Any(q => q(p)));

现在制作匿名对象Funcs列表的技巧(你可以轻松地将其改为“提取”匿名对象的类型)

static List<Func<T, bool>> MakeList<T>(IEnumerable<T> elements)
{
    return new List<Func<T, bool>>();
}

通过传递LINQ查询的结果来调用它。所以

var res = from p in elements select new { Id = p.Id, Val = p.Value };
var conditions = MakeList(res);

答案 1 :(得分:3)

var statusTexts = new List<string>(); // Add desired status texts
dataApplication.Where(item =>
        statusTexts.Any(status => item.Status == status))

答案 2 :(得分:0)

使用HashSet&lt;&gt;对于状态,那么.Contains将是O(1)而不是通常的列表&lt;&gt;的O(n):

var statuses = new HashSet<string>() {"a", "b", "c"};
var list = new[] {
    new {   Id = 1, status = "a"},
    new {   Id = 2, status = "b"},
    new {   Id = 3, status = "z"}
};

var filtered = list.Where(l => statuses.Contains(s => l.status == s));