如何让 EF Core 6 支持 DateOnly 类型

前言

上次,我们发现《DateOnly 和 TimeOnly 类型居然不能序列化》。

但问题还不仅仅如此。.

问题重现

假设有下列实体类:

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }        
    public DateOnly Birthday { get; set; }
}

由于Birthday只需要日期,所以我们使用了DateOnly类型。

但是,在使用 EF Core 6 存储到数据库时,出现如下错误:如何让 EF Core 6 支持 DateOnly 类型由于数据库没有 DateOnly 类型,我们使用的是 datetime 类型

结果DateOnly不能被 Map 成datetime数据库类型。

重载 OnModelCreating

根据提示,我们重载了OnModelCreating方法,发现有个HasColumnType方法,用于配置属性在面向关系数据库时映射到的列的数据类型:

modelBuilder.Entity<User>()
  .Property(t => t.Birthday)
    .HasColumnType("datetime");

但是,没有任何效果。

HasConversion 方法

继续查找,发现还有个HasConversion方法,用于配置属性,以便在写入数据库之前转换属性值并在从数据库中进行读取时转换回:

modelBuilder.Entity<User>()
  .Property(t => t.Birthday)
    .HasConversion(
        d => d.ToDateTime(TimeOnly.MinValue),
        d => DateOnly.FromDateTime(d));

现在,EF Core 6 已经可以正确地处理 DateOnly,并使用datetime数据库类型来存储它。

结论

今天,我们介绍了使用转换器来告诉 EF Core 6 如何处理 DateOnly。