簡體   English   中英

具有值或 null 的實體框架 LINQ

[英]Entity framework LINQ with value OR null

我有以下 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)

注意:沒有員工記錄的 ID 值為 NULL,它返回 0 而不是所有員工

如何為此Id=@empId OR Id IS NULL編寫 linq ?

您說這是您期望的查詢:

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

但是我很確定不是,因為Id永遠不會為null(您在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();

因此,僅在給出參數的情況下進行過濾。 然后,這將僅返回一個記錄。

LINQ to SQL 轉換簡化了您的查詢邏輯。 它們在功能上是等效的。

您不應該嘗試以生成您期望的特定 SQL 的方式編寫 LINQ。 您正在編寫 LINQ 來執行特定操作。 如果結果查詢與您的期望不符,請嘗試了解原因。

當您的比較是(Id=@empId OR Id IS NULL)

  • 如果@empId始終為 NULL,則(Id IS NULL)是功能等效的簡化
  • 如果@empId是一個值或可能為空,則(Id=@empId)是功能等效的簡化

您沒有說明您在 Entity Framework 中使用哪個 DB / DB 驅動程序,但您可以驗證與 NULL 比較總是錯誤的:

SELECT CASE WHEN NULL = NULL THEN 1 ELSE 0 END

MS SQL Server 為此查詢返回0 所以NULL不等於NULL。

數據庫引擎對 NULL 的解釋和處理通常與 C# 對 null 的處理略有不同。 NULL 是unknown而不是unset 在 MS SQL Server 中, IS NULL用於與 NULL 進行比較,而不是=!=<>

對於 MS SQL Server,請參閱NULL 和 UNKNOWN

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM