Search code examples
c#entity-frameworkone-to-onefluentef-fluent-api

Entity Framework 1-to-1 relationship does not throw an exception when dependent entity is null


I'm trying to do a 1-to-1 mapping in Entity Framework and one example I found online was here, look for the 'Configure One-to-One relationship using Fluent API section'

Most of the examples online is somewhat similar to the link, as well in some books that I've read while trying to implement this.

Here are my entities:

public class Student
{
    public Student() { }

    public int StudentId { get; set; }
    public string StudentName { get; set; }

    public virtual StudentAddress Address { get; set; }

}

public class StudentAddress
{
    public int StudentId { get; set; }

    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public int Zipcode { get; set; }
    public string State { get; set; }
    public string Country { get; set; }

    public virtual Student Student { get; set; }
}

My data context that includes configuration using the fluent api:

public class DataContext : DbContext
{
    public DbSet<Student> Student { get; set; }

    // public DbSet<StudentAddress> Addresses { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // Configure StudentId as PK for StudentAddress
        modelBuilder.Entity<StudentAddress>()
            .HasKey(e => e.StudentId);

        // Configure StudentId as FK for StudentAddress
        modelBuilder.Entity<Student>()
                    .HasRequired(s => s.Address)
                    .WithRequiredPrincipal(ad => ad.Student);
    }
}

class Program
{
    static void Main(string[] args)
    {
        using (var context = new DataContext())
        {
            var student = new Student { StudentName = "sample name" };
            context.Student.Add(student);
            context.SaveChanges();
        }
        Console.ReadKey();
    }
}

In the console application, I expect it throw an exception since a Student must have a StudentAddress in order for it be saved, but when I ran the application and checked the database the student entry actually got saved. I might be missing something under the hood, though if I try adding the [Required] attribute on top of the StudentAddress property of the Student class, it throws an exception if I don't supply a StudentAddress for a Student Entity.


Solution

  • I filed a bug to the EF team and here's the explanation why it behaves that way.

    https://github.com/aspnet/EntityFramework6/issues/66#issuecomment-248073084

    From Arthur Vickers (member of the EF dev team):

    EF will always let you insert a new principal (Student in your model) without any dependents regardless of whether the relationship is required or not. A required relationship means that a dependent (Address in your model) cannot be inserted without a corresponding principal. I realize that the way relationships are modeled in EF6 implies something different, but the decision to describe relationships in this way and then behave like this was made many years ago and we cannot change it now.