如何构建正确的LINQ查询(生成OR而不是AND)

时间:2012-11-08 16:06:24

标签: sql linq

我需要一些帮助来构建正确的查询。我有一个Employees表。我需要获得所有员工的列表,EENO(员工ID)包含来自提供的部分员工ID数组的字符串。

当我使用此代码时

// IEnumerable<string> employeeIds is a collection of partial Employee IDs
IQueryable<Employee> query = Employees;
foreach (string id in employeeIds)
{
    query = query.Where(e => e.EENO.Contains(id));
}
return query;

我会得到类似的东西:

SELECT * 
FROM Employees 
WHERE EENO LIKE '%1111111%' 
  AND EENO LIKE '%2222222%' 
  AND EENO LIKE '%3333333%' 
  AND EENO LIKE '%4444444%' 

哪个没有意义。 我在结果SQL中需要“OR”而不是“AND”。

谢谢!

更新

当我需要包含这些员工时,我使用PredicateBuilder 编写的代码完美无缺

var predicate = PredicateBuilder.False<Employee>();
foreach (string id in employeeIds)
{
    var temp = id;
    predicate = predicate.Or(e => e.EENO.Contains(temp));
}
var query = Employees.Where(predicate);

现在,我需要编写相反的代码,以排除这些员工, 这是但它无法正常工作:生成的SQL非常奇怪。

var predicate = PredicateBuilder.False<Employee>();
foreach (string id in employeeIds)
{
    var temp = id;
    predicate = predicate.And(e => !e.EENO.Contains(temp)); // changed to "And" and "!"
}
var query = Employees.Where(predicate);
return query;

它应该像这样生成SQL Where子句:

WHERE EENO NOT LIKE '%11111%'
       AND NOT LIKE '%22222%'
       AND NOT LIKE '%33333%'

但它没有发生

生成的SQL是:http://i.imgur.com/9MDP7.png

感谢任何帮助。感谢。

4 个答案:

答案 0 :(得分:3)

而不是foreach,只需构建一次IQueryable:

query = query.Where(e => employeeIds.Contains(e.EENO));

答案 1 :(得分:2)

我会看一下http://www.albahari.com/nutshell/predicatebuilder.aspx。这有很好的构建或查询方式,由编写LinqPad的人编写。以上链接也有使用示例。

答案 2 :(得分:1)

我相信你可以使用Any()

var query = Employees.Where(emp => employeeIds.Any(id => id.Contains(emp.EENO)));

答案 3 :(得分:1)

如果您不想使用谓词构建器,那么唯一的另一个选项是在中间查询上将每个集合UNION一起:

// IEnumerable<string> employeeIds is a collection of partial Employee IDs
IQueryable<Employee> query = Enumerable.Empty<Employee>().AsQueryable();
foreach (string id in employeeIds)
{
    string tempID = id;
    query = query.Union(Employees.Where(e => e.EENO.Contains(tempID));
}
return query;

另请注意,关闭规则将破坏您的谓词,并且最终只会根据您的上一个条件进行过滤。这就是为什么我在tempID循环中有foreach变量。

编辑:所以这里是您遇到的所有问题的概要:

生成OR而不是ANDS

完成,使用PredicateBuilder。

仅应用了上一个谓词

通过在内循环中分配临时变量(由于闭包规则)来解决问题

排除谓词不起作用

您需要从正确的基本案例开始。当您使用OR时,您需要确保首先使用false案例,这样您只包含至少一个谓词匹配的记录(否则不返回任何内容)。这样做的原因是,为了评估的目的,应该忽略基本情况。换句话说,false || predicate1 || predicate2 || ...实际上只是predicate1 || predicate2 || ...因为你在谓词列表中寻找至少一个true(并且你只需要一个基础来构建)。相反的情况适用于AND案例。您从true开始,以便为了评估而“忽略”它,但您仍需要一个基本案例。换句话说:true && predicate1 && ...predicate1 && ...相同。希望能解决你的上一期。