Dilshod K
Dilshod K

Reputation: 3082

EF Core saves null value of required property

I have three classes:

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
{

}

I want to make string DOB as required and I am doing this:

    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);
    }

In SQL EF Core is generating nullable column:

SQL

And it is allowing to save data when DOB is null:

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

SQLResult

However, It is working without inheritance. Is it an EF Core issue or I am missing something in model mapping?

EDIT: I replaced DateTime? to string because the issue is not related to the type of property

Upvotes: 5

Views: 2524

Answers (3)

Ivan Stoev
Ivan Stoev

Reputation: 205539

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

It is indeed EF Core issue, which also is observed in the EFC 5.0 release candidate, so it won't be addressed (except if you change the database design to utilize TPT).

First, unlike EF6, EF Core does not perform validations in general. Instead, it relies on the underlying database to do that.

Second, since the TPH database inheritance strategy stores all data in a single table, the derived entity data columns must allow null, even though they are required, otherwise you won't be able to store Teacher entity data for instance.

The combination of the two aforementioned behaviors leads to the unexpected behavior of allowing null value for the required field of a derived entity.

Therefore there is nothing you could do at mapping side (neither fluently nor with [Required] data annotation). The necessary validations should be performed by the business logic layer outside the EF Core.

Upvotes: 5

heijp06
heijp06

Reputation: 11788

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

I am going to suggest just that, define DOB as:

public DateTime DOB { get; set; }

EF Core uses Table-per-hierarchy here. It is clever enough to figure out that required properties on child types need to be NULL in the database because it needs to be able to store other childs (Teacher) and the base type (Person) where the required property is missing.

I think you are trying to solve a problem that is solved in EF Core itself.

Upvotes: 0

Nasr Aldin
Nasr Aldin

Reputation: 1

I think your property will be null when no value is present and your Required attribute will behave as expected. try to add Required as an annotation on prop maybe work

Upvotes: -2

Related Questions