【问题标题】:Nullable Guid in Linq to Sql Yields Unexpected ResultLinq to Sql 中的 Nullable Guid 产生意外结果
【发布时间】:2012-03-30 12:02:52
【问题描述】:

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

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

如果我随后构造一个 Linq 表达式以通过 Name 和 ParentCategoryId 查找特定类别,我发现如果我设置了 Guid,我将无法获得正确的结果?变量为空:

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 为第一个 Guid 生成的 SQL 语句? 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 与空参数进行比较,而第二个方法检查 ParentCategoryId IS NULL - 这是正确的

【问题讨论】:

  • 如果休息从 1 开始,为什么不把 parentid 放在第一位。
  • 你能展示它生成的sql select语句吗?
  • 有什么不同的结果。

标签: c# linq-to-sql nullable


【解决方案1】:

不,不幸的是,这是一个相当普遍的问题。解决方法是显式与 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);

【讨论】:

  • 谢谢乔恩,您的解决方法效果很好并且解决了问题。在代码级别很容易错过这个问题,因此在比较可空类型时,自我注释要非常小心。感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 2011-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-17
  • 2012-09-03
相关资源
最近更新 更多