Linq到Sql中的Nullable Guid产生了意想不到的结果

时间:2012-03-30 12:02:53

标签: c# linq-to-sql nullable

我有一个简单的SQL表,它定义了一组分层类别和子类别 - 请注意,对于“顶级”类别,ParentCategoryId可以为null ...

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

如果我构建一个Linq表达式以通过Name和ParentCategoryId查找特定类别,我发现如果设置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? null参数,然后是一个简单的null参数:

-- 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 - 这是正确的

1 个答案:

答案 0 :(得分:8)

不,不幸的是,这是一个相当普遍的问题。解决方法是与null明确比较:

.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);