2

我需要一些帮助来构建正确的查询。我有一个员工表。我需要获取所有员工的列表,该 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

4 回答 4

3

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

query = query.Where(e => employeeIds.Contains(e.EENO));
于 2012-11-08T16:09:00.247 回答
2

我会看看http://www.albahari.com/nutshell/predicatebuilder.aspx。这是构建 Or 查询的好方法,由编写 LinqPad 的人编写。上面的链接也有使用示例。

于 2012-11-08T16:09:41.547 回答
1

我相信你可以使用Any()

var query = Employees.Where(emp => employeeIds.Any(id => id.Contains(emp.EENO)));
于 2012-11-08T17:20:06.650 回答
1

如果您不想使用谓词构建器,那么唯一的其他选择是在中间查询中将每个集合联合起来:

// 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。

仅应用最后一个谓词

通过在内部循环中分配一个临时变量来解决(由于关闭规则)

排除谓词不起作用

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

于 2012-11-08T17:26:04.520 回答