Unable to determine the principal end of an association - Entity Framework Model First

37,166

You have to specify the principal in a one-to-one relationship.

public partial class Address
{
    [Key, ForeignKey("User")]
    public int Id { get; set; }
    public string Street { get; set; }
    public string StreetNumber { get; set; }
    public string City { get; set; }
    public string ZipCode { get; set; }
    public string Country { get; set; }

    public virtual User User { get; set; }
}

By specifying a FK constraint, EF knows the User must exists first (the principal) and the Address follows.

Further reading at MSDN.

Also, see this SO answer.


Updated from comments


In the designer, select the association (line between Users & Address). On the properties window, hit the button with the [...] on Referential Constraint (or double click the line). Set the Principal as User.


Share:
37,166
Michal
Author by

Michal

Updated on September 23, 2020

Comments

  • Michal
    Michal over 3 years

    I have created Entity Data Model in Visual Studio. Now I have file with SQL queries and C# classes generated from Model.

    Question:

    Classes are generated without annotations or code behind (Fluent API). Is it OK? I tried to run my application but exception was thrown:

    Unable to determine the principal end of an association between the types 'Runnection.Models.Address' and 'Runnection.Models.User'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

    I read that I can not use Fluent API with "Model First". So what can I do?

    Code:

    User

    public partial class User
    {
        public User()
        {
            this.Events = new HashSet<Event>();
            this.CreatedEvents = new HashSet<Event>();
        }
    
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Photo { get; set; }
        public int EventId { get; set; }
        public string Nickname { get; set; }
        public OwnerType OwnerType { get; set; }
        public NetworkPlaceType PlaceType { get; set; }
    
        public virtual ICollection<Event> Events { get; set; }
        public virtual Address Address { get; set; }
        public virtual ICollection<Event> CreatedEvents { get; set; }
        public virtual Owner Owner { get; set; }
    }
    

    Address

    public partial class Address
    {
        public int Id { get; set; }
        public string Street { get; set; }
        public string StreetNumber { get; set; }
        public string City { get; set; }
        public string ZipCode { get; set; }
        public string Country { get; set; }
    
        public virtual User User { get; set; }
    }
    

    Context

    //Model First does not use this method

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Address>().HasRequired(address => address.User)
                                       .WithRequiredDependent();
            modelBuilder.Entity<User>().HasRequired(user => user.Address)
                                       .WithRequiredPrincipal();
    
            base.OnModelCreating(modelBuilder);
        }
    
  • Michal
    Michal about 10 years
    Yes I know It is a option. But code is auto-generated from model. In case that Model will be changed, I must specify annotation to class again.
  • Eric W.
    Eric W. about 10 years
    Ok, answer is updated. Just double click the line between the entities and set the principal in the window that opens.
  • Michal
    Michal about 10 years
    Thank you, but it does not help because Referential Constraint was already defined :(.
  • Eric W.
    Eric W. about 10 years
    I'm sorry that I can't be be of further help. Hopefully someone else can help answer this. In the mean time, you may want to try a 0..1 mapping. You may also want to consider a microORM like SO's own Dapper.NET. A bit more typing, but less unpredictable behavior and better performance.
  • rory
    rory over 9 years
    "By specifying a FK constraint, EF knows the User must exists first (the principal) and the Address follows." thank you thank you thank you!
  • Tsar Bomba
    Tsar Bomba over 7 years
    @Michal Why wasn't this marked as the accepted answer? You could drop and re-create your constraint and this would be your solution. Regardless, this is how a 1-1 is defined in EF and would help just about anyone else with the same question.