【问题标题】:How can I prevent the default value of DateTimeOffset from being inserted?如何防止插入 DateTimeOffset 的默认值?
【发布时间】:2021-01-19 17:39:55
【问题描述】:

我正在使用 Entity Framework Core 3.1.7 并创建了一个名为 Event 的实体,我是这样设置的:

public class Event
{
    public long Id { get; set; }
    public DateTimeOffset FirstOccurred { get; set; }
}

实体配置如下:

builder.Property(e => e.FirstOccurred)
    .IsRequired();

我使用我的dbContext 来保存这样的实体:

await dbContext.Events.AddAsync(new Event());

在这种情况下,我错误地预期会在数据库级别引发异常,因为该值不能为空。

实际发生的情况是:实体很高兴地将FirstOccurred 设置为0001-01-01T00:00:00+00:00

这是有道理的,因为使用了默认值DateTimeOffset

现在我的问题是:如何改进我的设计以防止插入此默认值?

我已经有了一些想法:

  1. 保持上面的代码不变,但请确保无论在何处使用实体,我都正确设置了值。缺点:无法保证随着时间的推移,这将在团队中始终如一地应用。
  2. 使DateTimeOffset 可以为空,这在上面的AddAsync() 调用中实际上会导致SQL 异常。缺点:乍一看,DateTimeOffset? FirstOccurred 可能会让人感到困惑,因为实际的数据库约束不允许 null
  3. FirstOccurred 删除set; 并创建一个需要设置此属性的构造函数,例如new Event(DateTimeOffset.Now)

【问题讨论】:

  • “我希望在数据库级别引发异常,因为该值不能为空。”不过,它不是空的。您已经创建了一个 Event 的新实例,它声明了它的 FirstOccurred 属性。由于该属性不可为空,因此将其设置为 default(DateTimeOffset)
  • 是的,你是对的。我将稍微改写我的假设,以澄清我在这里想说的话。谢谢

标签: entity-framework-core entity-framework-core-3.1


【解决方案1】:

我认为你的最后一个想法是正确的。

FirstOccurred 删除set; 并创建一个需要设置此属性的构造函数,例如new Event(DateTimeOffset.Now)

跟踪没有时间戳的事件是没有意义的,使用时间戳的默认值当然没有意义。

将您的模型更改为需要时间戳值可确保您不会将默认数据写入记录,并防止在相应的表列不可为空时看到可空模型字段而产生混淆。

public class Event {
    public Event (DateTimeOffset firstOccurred) { FirstOcurred = firstOcurred; }
    public long Id { get; set; }
    public DateTimeOffset FirstOccurred { get; set; }
}

只是来自documentation 的注释,不要删除set; 访问器,如果您不希望在构造后更改值,只需将其标记为private

一旦通过构造函数设置属性,就可以将其中的一些设置为只读。 EF Core 支持这一点,但需要注意一些事项:

没有设置器的属性不按约定映射。 (这样做往往会映射不应映射的属性,例如计算属性。) 使用自动生成的键值需要一个可读写的键属性,因为在插入新实体时需要由键生成器设置键值。 避免这些事情的一个简单方法是使用私有 setter。

当然,您还可以通过覆盖属性的默认值来保持无参数构造函数的灵活性。

public class Event {
    public long Id { get; set; }
    public DateTimeOffset FirstOccurred { get; set; } = DateTimeOffset.Now;
}

【讨论】:

  • 我觉得你写的很有意义,谢谢。我会将这个问题再留几天,如果没有其他答案出现,我会将其标记为“已接受”
猜你喜欢
  • 1970-01-01
  • 2011-07-06
  • 1970-01-01
  • 2013-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-10
相关资源
最近更新 更多