Configuring one-to-many and one-to-one relationship in Entity Framework Core

entity-framework entity-framework-core


I'm quite new to Entity Framework and am picking it up with the Core version. I'm trying to understand how to customise model relationships.

My basic model is that I have a Company entity, and a Contact entity. A Company can have many Contacts. A company can a KeyContact, which must be one of the associated contacts, but is not required.

Thus there is a One to Many relationship, but also a One to One relationship. I've tried to implement this as below (removed most other fields for clarity);

public class Company
    public int Id { get; set; }
    public int? KeyContactId { get; set; }
    public ICollection<Contact> Contacts { get; set; }
    public Contact KeyContact { get; set; }

public class Contact
    public int Id { get; set; }
    public int CompanyId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public Company Company { get; set; }

It fails to add this migration with the message;

Unable to determine the relationship represented by navigation property 'Company.Contacts' of type 'ICollection'. Either manually configure the relationship, or ignore this property from the model.

I can kinda see why it's complaining about this, but I'm not sure if there's a way with the model builder I can configure this, or whether it's an invalid pattern. My model builder is currently just basic;

protected override void OnModelCreating(ModelBuilder modelBuilder)


I know I could just have a flag to say IsKeyContact in the contact table, but I like the idea of having the navigation property in the company entity. So I'm wondering how sugary Entity can be.

Any help much appreciated.



9/6/2017 10:54:26 AM

Popular Answer

The exception is avoided by adding the following line to the OnModelCreating method:

modelBuilder.Entity<Company>().HasMany(p => p.Contacts).WithOne(d => d.Company).HasForeignKey(d => d.CompanyId);

This configures the Company.Contacts-Contact.Company relation. By default, the Company.KeyContact relation is configured as if the following line would be within the OnModelCreating method:

modelBuilder.Entity<Company>().HasOne(e => e.KeyContact).WithMany().HasForeignKey(e => e.KeyContactId);

Hence a Contact can be the KeyContact of more than one Company. In order to ensure that a Contact can be the KeyContact of at most one Company the Company.KeyContact relation could be configured by the following line within the OnModelCreating method:

modelBuilder.Entity<Company>().HasOne(e => e.KeyContact).WithOne().HasForeignKey<Company>(e => e.KeyContactId);

But note: This will not ensure that the KeyContact is a member of the Contacts.

9/4/2018 1:29:29 PM

Related Questions


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow