我需要一些帮助来构建正确的查询。我有一个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
感谢任何帮助。感谢。
答案 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 && ...
相同。希望能解决你的上一期。