有值()或 ??在 LINQ-to-Entity 中处理可空类型时的操作数,

HasValue() or ?? operand when dealing with nullable types in LINQ-to-Entity,

我有以下代码为可为空的 int 变量赋值:

ParentCommentId = lac.ParentCommentId ?? lac.ParentCommentId.Value,

但是,使用此代码我收到 Nullable object must have a value 错误。

然后,我修改了代码如下:

ParentCommentId = lac.ParentCommentId.HasValue ? lac.ParentCommentId.Value : null,

而且,现在一切正常。我想知道为什么 ?? 操作数在这种情况下不起作用。我用错了吗?在什么情况下,??更合适?

Nullable object must have a value 是一个运行时异常,当您尝试访问 .HasValue false 的可空对象的 .Value 时发生。

您的代码:

ParentCommentId = lac.ParentCommentId ?? lac.ParentCommentId.Value

翻译成:

if (lac.ParentCommentId.HasValue)
{
    ParentCommentId = lac.ParentCommentId.Value;
}
else
{
    ParentCommentId = lac.ParentCommentId.Value;
}

如您所见,两个分支都在做同样的事情,即使 HasValue 为假(并且会导致该异常),您也将访问 .Value

运算符??用于取第一个非空值。你可以写

var value = value1 ?? value2 ?? value3;

value1value2value3中第一个不是null的将分配给value,如果都是null ] 那么 value 将被设置为 null.

ParentCommentId = lac.ParentCommentId ?? lac.ParentCommentId.Value, I wonder why ?? operand does not work in this case.

当您使用 null-coalescing operator ?? 时,它是 shorthand 一组简短的步骤,一般意义上的步骤执行以下操作

  1. lac.ParentCommentId是不是可以null的东西?
    是 -> 继续
    否 -> 给出一个编译器错误,说你不能在不能为 null 的东西上使用 ?? 运算符,因为它是 null-coalescing operator.

  2. lac.ParentCommentIdnull吗?
    是 -> 继续
    否 -> 将 ParentCommentId 的值设置为 lac.ParentCommentId 的值,如果它们是同一类型。

  3. ParentCommentId 的值设置为 lac.ParentCommentId.Value 的值,如果它们是同一类型。

当您分解 ?? 运算符的作用时,您会发现它在第 2 步附近遇到了问题。

想要的是当lac.ParentCommentId有值时,将ParentCommentId设置为lac.ParentCommentId.Value

但是,当您使用 ?? 时,您并不是这样做的。相反,您好像在说 'When lac.ParentCommentId has a value, set ParentCommentId to lac.ParentCommentId'.

有一种方法可以解决这个问题,它实际上非常简单,因为 lac.ParentCommentId 已经是一个可以为 null 的值,我们可以简单地使用

ParentCommentId = lac.ParentCommentId ?? AlternativeValue

如果我们还认为 nullParentCommentId 的可接受值,我们实际上可以进一步简化它以获得更优雅的解决方案并使用:

ParentCommentId = lac.ParentCommentId

编辑:以下仅适用于 LINQ-to-Objects,不适用于实体框架。它保留为有关 ? 空合并运算符的附加信息。感谢 Ivan Stoev 指出这一点!

如果 lac.ParentCommentId.Value 是一个可以为 null 的值,您可以改用这个:

ParentCommentId = lac?.ParentCommentId.Value ?? AlternativeValue,

它的作用是检查 ANY of lac ParentCommentId OR Value 是否为空,如果 ANY其中null,使用替代值。