EF Core 保存所需 属性 的空值

EF Core saves null value of required property

我有三个类:

public class Person
{
    public string Name { get; set; }
    public Guid Guid { get; set; }
}

public class Student : Person
{
    public string DOB { get; set; }
}


public class Teacher : Person
{

}

我想根据需要制作字符串 DOB,我正在这样做:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Person>().HasKey(d => d.Guid);
        modelBuilder.Entity<Student>().Property(d => d.DOB).IsRequired(true);
        modelBuilder.Entity<Teacher>();
        base.OnModelCreating(modelBuilder);
    }

在 SQL 中,EF Core 正在生成可为空的列:

并且当DOB为空时允许保存数据:

MainContext mainContext = new MainContext();
        mainContext.Add(new Student() { DOB = null });
        mainContext.SaveChanges();

但是,它在没有继承的情况下工作。是 EF Core 问题还是我在模型映射中遗漏了什么?

编辑: 我将 DateTime? 替换为 string 因为问题与 属性

的类型无关

我认为当没有值时您的 属性 将为 null,并且您的 Required 属性将按预期运行。尝试在 prop 上添加 Required 作为注释可能有效

Please don't suggest me to make it DateTime DOB.

我只是建议,将 DOB 定义为:

public DateTime DOB { get; set; }

EF Core 在此处使用 Table-per-hierarchy。很聪明地发现子类型的必需属性在数据库中需要为 NULL,因为它需要能够存储其他子类型 (Teacher) 和缺少所需 属性 的基本类型 (Person) .

我认为您正在尝试解决 EF Core 本身已解决的问题。

Is it an EF Core issue or I am missing something in model mapping?

这确实是 EF Core 问题,在 EFC 5.0 候选发布版中也观察到,因此不会解决(除非您更改数据库设计以使用 TPT)。

首先,与 EF6 不同,EF Core 通常不执行验证。相反,它依赖于底层数据库来执行此操作。

其次,由于 TPH 数据库继承策略将所有数据存储在单个 table 中,派生实体数据列必须允许 null,即使它们是必需的,否则您将无法存储 Teacher 例如实体数据。

上述两种行为的组合导致派生实体的必填字段允许空值的意外行为。

因此,在映射方面您无能为力(既不流畅也不使用 [Required] 数据注释)。必要的验证应由 EF Core 外部的业务逻辑层执行。