实体框架LINQ,值为OR

时间:2018-01-17 11:32:29

标签: c# entity-framework linq entity-framework-6

我有以下EF linq查询来获取所有雇员或特定雇员,以防empId有价值。

但是EF没有生成预期的查询,它忽略了OR条件总是

from employee 
where employee.DepartmentId == depId && ((employee.Id == empId) || (employee.Id == null))
.ToList()

预期查询

SELECT * FROM Employee
WHERE DepartmentId = @DepId AND (Id=@empId OR Id IS NULL)

传递值时由EF生成的查询

SELECT * FROM Employee
WHERE DepartmentId = @DepId AND (Id=@empId)

当值为空时由EF生成查询

SELECT * FROM Employee
WHERE DepartmentId = @DepId AND (Id IS NULL)
  

注意:没有Employee记录的Id值为NULL,它返回0而不是   所有员工

如何为此Id=@empId OR Id IS NULL撰写linq?

1 个答案:

答案 0 :(得分:5)

你说这是你期望的查询:

SELECT * FROM Employee
WHERE DepartmentId = @DepId AND (Id=@empId OR Id IS NULL)

但是我很确定它不是,因为Id永远不会为空(你在 Note 中也说过),因为它是该表的主键。你实际上是指这个查询:

SELECT * FROM Employee
WHERE DepartmentId = @DepId AND (Id=@empId OR @empId IS NULL)

因此,如果参数为NULL,您希望绕过检查并返回所有记录。请注意,这不是性能明智的最佳方式。如果您不想按Id进行过滤,则应使用不带过滤器的查询。我担心这不会产生最有效的查询计划。我会用这个:

IQueryable<Employee> allDepartmentEmployees = 
    from employee in ...
    where employee.DepartmentId == depId;
    select employee;

if(empId.HasValue) // presuming it's a nullable type
{
    allDepartmentEmployees = allDepartmentEmployees.Where(e => e.Id == empId.Value);     
}

List<Employee> employeeList = allDepartmentEmployees.ToList();

因此,只有在给出参数时才进行过滤。然后这只会返回一条记录。