Configuring One To One Relationships In Entity Framework Core

Entity Framework Core configures one to one relationships by being able to detect the foreign key property, and thereby identify which is the principal and which is the dependent entity in the relationship. If it is unable to do this, either because the foreign key property name does not follow convention, or because it has not been included in the model, an error message is provided when you attempt to create a migration:

The child/dependent side could not be determined for the one-to-one relationship that was detected between '<entity1.property2>' and '<entity2.property1>'. To identify the child/dependent side of the relationship, configure the foreign key property.

In the following model, the AuthorRef foreign key property in the AuthorBiography entity (the dependant in the relationship) does not follow foreign key naming convention:

public class Author
    public int AuthorId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public AuthorBiography Biography { get; set; }

public class AuthorBiography
    public int AuthorBiographyId { get; set; }
    public string Biography { get; set; }
    public DateTime DateOfBirth { get; set; }
    public string PlaceOfBirth { get; set; }
    public string Nationality { get; set; }
    public int AuthorRef { get; set; }
    public Author Author { get; set; }

As a result, EF Core will not be able to detect the dependent entity in the relationship. It is configured using the Fluent API like this:

protected override void OnModelCreating(ModelBuilder modelBuilder)
        .HasOne(a => a.Biography)
        .WithOne(b => b.Author)
        .HasForeignKey<AuthorBiography>(b => b.AuthorRef);

The Has/With pattern is used to close the loop and fully define a relationship. In this case, since the relationship to be configured is a one-to-one, the HasOne method is chained with the WithOne method. Then the dependent entity (AuthorBiography) is identified by passing it in as a type parameter to the HasForeignKey method, which takes a lambda specifying which property in the dependent type is the foreign key.

Further Reading

Last updated: 14/03/2017 16:33:40
Proficiency Level: Beginner