2012-03-30 98 views
3

我有一個定義了一套分層分類和子類的一個簡單的SQL表 - 注意ParentCategoryId可爲空的「頂級」類別...可空的Guid LINQ to SQL中,則會產生意外結果

CREATE TABLE [dbo].[Category](
    [CategoryId] [uniqueidentifier] NOT NULL, 
    [ParentCategoryId] [uniqueidentifier] NULL, 
    [Name] [nvarchar](50) NOT NULL 
) 

如果我然後通過Name和ParentCategoryId構造一個Linq表達式來查找特定的類別,那麼如果我設置了Guid,我發現我無法得到正確的結果?變量設置爲null:

Guid? parentCategoryId = null; 

var category = dc.Categories 
    .Where(c => (
     (c.Name == "Fred") && 
     (c.ParentCategoryId == parentCategoryId) 
)); 

這不會產生相同的結果爲:

var category = dc.Categories 
    .Where(c => (
     (c.Name == "Fred") && 
     (c.ParentCategoryId == null) 
)); 

從我可以在網上找到,其他人都有過這樣的問題,但我一直沒能找到一個乾淨的解決方法來解決這個問題。

任何想法將不勝感激。謝謝。

其他信息 這是LINQ生成的SQL語句首先是Guid?空參數,然後一個簡單的空參數:

-- With Guid? null parameter : return an empty record set 
DECLARE @p0 NVarChar(1000) SET @p0 = 'Fred' 
DECLARE @p1 UniqueIdentifier SET @p1 = null 
SELECT [t0].[CategoryId], [t0].[ParentCategoryId], [t0].[Name], [t0].[Timestamp] 
FROM [dbo].[cad_ScoCategory] AS [t0] 
WHERE ([t0].[Name] = @p0) AND ([t0].[ParentCategoryId] = @p1) 


-- With null parameter - returns a single (correct) record 
DECLARE @p0 NVarChar(1000) SET @p0 = 'Fred' 
SELECT [t0].[CategoryId], [t0].[ParentCategoryId], [t0].[Name], [t0].[Timestamp] 
FROM [dbo].[cad_ScoCategory] AS [t0] 
WHERE ([t0].[Name] = @p0) AND ([t0].[ParentCategoryId] IS NULL) 

正如你可以看到,第一個選項ParentCategoryId用清零paraemeter其中作爲第二個方法檢查ParentCategoryId比較IS NULL - 這是正確的

+0

你爲什麼不把的parentId爲第一要如果休息從1開始,則爲零。 – 2012-03-30 12:04:39

+1

可以顯示其生成的sql select語句嗎? – 2012-03-30 12:04:48

+0

有什麼不同的結果。 – Hogan 2012-03-30 12:05:51

回答

8

無,不幸的是這是一個相當普遍的問題。解決方法是明確地空比較:

.Where(c => c.Name == Fred && 
      ((c.ParentCategoryId == parentCategoryId) || 
      (c.ParentCategoryId == null && parentCategoryId == null))) 

另外,執行檢查查詢(以改變使用的過濾器):

var category = dc.Categories.Where(c => c.Name == "Fred"); 
category = parentCategoryId == null 
    ? category.Where(c => c.ParentCategoryId == null) 
    : category.Where(c => c.ParentCategoryId == categoryId); 
+0

謝謝喬恩,你的解決方法運作良好,並克服了這個問題。在代碼級錯過這個問題很容易,所以在比較可爲空的類型時,注意到自己是非常謹慎的。謝謝你的幫助。 – Neilski 2012-03-30 13:31:59