Joe Joe - 1 month ago 9
C# Question

Entity Framework multiple One to One

I would like to use code first entity framework to setup a parent entity two instances of a child entity, each with a one to one relationship.

I tried using the following models:-

public class Parent
{
[Key]
public int Id { get; set; }

public virtual Child FirstChild { get; set; }

public virtual Child SecondChild { get; set; }
}

public class Child
{
[Key, ForeignKey("Parent")]
public int ParentId{ get; set; }

public Parent Parent { get; set; }
}


However when I try to add a child to a parent I get the following exception:-

context.Add(new Parent
{
FirstChild = new Child(),
SecondChild = new Child()
});
context.SaveChanges();



System.Data.Entity.Infrastructure.DbUpdateException : Conflicting
changes detected. This may happen when trying to insert multiple
entities with the same key.


I assume this means that the code is attempting to set both FirstChild and SecondChild to use the same Id as the Parent Id, which is invalid as they can't both have the same Primary Key. Is there a way to configure the models to allow two One to One links?

Answer Source

What you desire is NOT a one to one mapping. If you think deeply is a one to TWO mapping. In order to have this working in EF, you need to map as a one to many relation and hide the collection property from external usage.

public class Parent
{
    [Key]
    public int Id { get; set; }

    protected virtual List<Child> Children {get; set;}

    [Ignore]
    public Child FirstChild 
    { 
         get{ return Children[0]; }
         set{ Children[0] = value; } 
    }

    [Ignore]
    public Child SecondChild 
    { 
         get{ return Children[1]; }
         set{ Children[1] = value; } 
    }
}

public class Child
{
    [Key, ForeignKey("Application")]
    public int ApplicationId { get; set; }

    [Key, ForeignKey("Parent")]
    public int ParentId { get; set; }
    [Key]
    public int Id { get; set; }

    public Parent Parent { get; set; }
}

You may need to map this using the ModelBuilder configuration because the Attributes are not strong enough for this.