Entity Framework對NULL值的處理

今天拿Entity Framework改寫早期的一個項目,涉及到對NULL值處理的時候,遇到了點問題,就是如何查詢數據庫中某字段爲NULL的記錄,寫了幾個測試用的例子,然後用SQL Server Profiler抓SQL。


測試1:直接使用null

  1. var clients = ctx.Clients.Where(c => c.ParentGUID == null);

對應的SQL是:

  1. -- 執行正常
  2. SELECT 
  3. [Extent1].[GUID] AS [GUID], 
  4. [Extent1].[Name] AS [Name], 
  5. [Extent1].[ParentGUID] AS [ParentGUID]
  6. FROM [dbo].[Clients] AS [Extent1]
  7. WHERE [Extent1].[ParentGUID] IS NULL


測試2:使用等於null的變量:

  1. string parentGuid = null;
  2. var clients = ctx.Clients.Where(c => c.ParentGUID == parentGuid);

對應的SQL是:

  1. -- 使用了值爲NULL的變量,但是用了等號,所以取不到值了
  2. exec sp_executesql N'SELECT 
  3. [Extent1].[GUID] AS [GUID], 
  4. [Extent1].[Name] AS [Name], 
  5. [Extent1].[ParentGUID] AS [ParentGUID]
  6. FROM [dbo].[Clients] AS [Extent1]
  7. WHERE [Extent1].[ParentGUID] = @p__linq__0',N'@p__linq__0 varchar(8000)',@p__linq__0=NULL


測試3:加判斷

  1. string parentGuid = null;
  2. var clients = ctx.Clients.Where(c => c.ParentGUID == (string.IsNullOrEmpty(parentGuid) ? null : parentGuid));

  對應的SQL是:

  1. -- 無語了,這也整得太複雜了吧,顯然得不到正確結果
  2. exec sp_executesql N'SELECT 
  3. [Extent1].[GUID] AS [GUID], 
  4. [Extent1].[Name] AS [Name], 
  5. [Extent1].[ParentGUID] AS [ParentGUID]
  6. FROM [dbo].[Clients] AS [Extent1]
  7. WHERE [Extent1].[ParentGUID] = (
  8.     CASE 
  9.         WHEN ((@p__linq__0 IS NULL) OR (( CAST(LEN(@p__linq__0) AS int)) = 0)) 
  10.         THEN CAST(NULL AS varchar(1)) 
  11.         ELSE @p__linq__1 
  12.     END
  13. )',N'@p__linq__0 nvarchar(4000),@p__linq__1 nvarchar(4000)',@p__linq__0=NULL,@p__linq__1=NULL


測試4:另一種方式加判斷

  1. string parentGuid = null;
  2. var clients = ctx.Clients.Where(c => string.IsNullOrEmpty(parentGuid) ? c.ParentGUID == null : c.ParentGUID == parentGuid);

對應的SQL是:

  1. --繼續無語,比剛纔的還複雜,同樣得不到正確結果
  2. exec sp_executesql N'SELECT 
  3. [Extent1].[GUID] AS [GUID], 
  4. [Extent1].[Name] AS [Name], 
  5. [Extent1].[ParentGUID] AS [ParentGUID]
  6. FROM [dbo].[Clients] AS [Extent1]
  7. WHERE (
  8.     CASE 
  9.         WHEN ((@p__linq__0 IS NULL) OR (( CAST(LEN(@p__linq__0) AS int)) = 0)) 
  10.         THEN cast(0 as bit) 
  11.         
  12.         WHEN ([Extent1].[ParentGUID] = @p__linq__1) 
  13.         THEN cast(1 as bit) 
  14.         
  15.         WHEN ([Extent1].[ParentGUID] <> @p__linq__1) 
  16.         THEN cast(0 as bit) 
  17.     END
  18. ) = 1',N'@p__linq__0 nvarchar(4000),@p__linq__1 varchar(8000)',@p__linq__0=NULL,@p__linq__1=NULL

暈倒,看來把Linq的思想直接往EF上套是行不通的,某些情況下差異還是挺大的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章