如何在可空日期中使用空值合并运算符

7

我的视图模型有一个可为空的日期属性,例如...

[DataType(DataType.Date)]
public DateTime? SanctionExpires { get; set; }

但是当我尝试使用空值合并运算符时,比如...

var test = model.SanctionExpires.Value.ToUniversalTime() ?? model.SanctionExpires;

我遇到了以下错误...

运算符“??”无法应用于类型为“datetime”和“datetime”的操作数

我认为这应该可以工作,因为我将我的日期属性设置为可空,并且这篇文章也建议这样做。我做错了什么?

更新

为了更清楚地说明,我想使用null-coaslescing来分配一个Dapper参数,它将更新数据库中的DateTime字段。该字段可以接受空值或日期时间值。基本上,如果用户指定了日期,则将提供的日期分配给参数,否则将分配为null...

p.Add("@SanctionExpires", model.SanctionExpires.Value.ToUniversalTime() ?? model.SanctionExpires);

请注意,我必须进行UTC转换,因为我正在使用SQL Azure,它对日期使用UTC,否则如果我仅从我的本地系统传递数据,则时间会相差11小时(我在澳大利亚)。在SQL中,我使用一个函数将日期偏移到我的时区,然后再更新表格。
目前我用的解决方案如下,但不确定这是否是最简洁的方式。希望能够一行代码解决问题...
if (model.SanctionExpires == null)
    p.Add("@SanctionExpires", model.SanctionExpires);
else
    p.Add("@SanctionExpires", model.SanctionExpires.Value.ToUniversalTime());

你的问题并不完全有意义。为了让我们和你理解,尝试移除你的变量并包含一个实际类型 - 你想要输出什么? - Paddy
1
SanctionExpires 是一个 Nullable<DateTime>,但是 SanctionExpires.Value 是一个 DateTime - Dennis_E
model.SanctionExpiresnull 时,您希望 test 取什么值?(如果此代码编译,则会得到 NullReferenceException) - Hans Kesting
2个回答

15

.Value对可空类型假设它不会为null。因此,在其上应用空值合并运算符是无用和禁止的。

你可以像这样使用该运算符,但是根据你的代码,我不确定这是否是你需要的:

DateTime test = (model.SanctionExpires ?? DateTime.Now).ToUniversalTime();

针对你的更新:你可以像这样简化评估:

DateTime? test = model.SanctionExpires?.ToUniversalTime();

我已经更新了我的问题以更好地解释我的目标。是否可能在一行中实现,或者这将是最清晰的选项...if (model.SanctionExpires == null) p.Add("@SanctionExpires", model.SanctionExpires); else p.Add("@SanctionExpires", model.SanctionExpires.Value.ToUniversalTime()); - OjM
谢谢,你的一行代码完美地解决了问题。我的最终代码是 p.Add("@SanctionExpires", model.SanctionExpires?.ToUniversalTime() ?? model.SanctionExpires); - OjM

1
你还可以使用GetValueOrDefault方法来返回默认值,如果你的DateTime对象为空。如果你想使用实际日期,应该使用DateTime.Now

例如,以下代码片段可以帮助你:

var defaultDateTime = DateTime.Now;
var dateTime = model.SanctionExpires.GetValueOrDefault(defaultDateTime).ToUniversalTime();

如果您调用GetValueOrDefault而不使用参数,则会在DateTime为空时使用default(DateTime)
var dateTime = model.SanctionExpires.GetValueOrDefault().ToUniversalTime(); //dateTime == default(DateTime) in case !model.SanctionExpires.HasValue

更新

如果你正在使用 C#5.0 或更低版本,你可以使用以下代码片段,因为 NULL 条件运算符 只在 C#6.0 之后才可用。

p.Add("@SanctionExpires", !model.SanctionExpires.HasValue ? null : (DateTime?)model.SanctionExpires.Value.ToUniversalTime());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接