Reputation: 631
I have the following model.
public class Parent
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
public class Child
{
public int Id { get; set; }
public string Name { get; set; }
public int ParentId { get; set; }
public virtual Parent Parent { get; set; }
}
In the following code, EF inserts both parent and child objects into the database with dbo.Child.ParentId
field referencing dbo.Parent.Id
, even though child.ParentId
property was never set .
var parent = new Parent { Name = "p_1" };
var child = new Child { Name = "ch_1" }; // ParentId == 0
var con = new MyContext();
con.Set<Child>().Add(child);
con.Set<Parent>().Add(parent);
con.SaveChanges(); // saved successfully
But in the below code, EF is unable to save changes throwing this exception:
Unable to determine the principal end of the 'TestEfProxy.Child_Parent' relationship. Multiple added entities may have the same primary key.
Code:
var parent = new Parent { Name = "p_1" };
var parent2 = new Parent { Name = "p_2" };
var child = new Child { Name = "ch_1" };
var con = new MyContext();
con.Set<Parent>().Add(parent);
con.Set<Child>().Add(child);
con.Set<Parent>().Add(parent2);
con.SaveChanges(); // throws exception
Why does EF decide that child.ParentId
references parent.Id
in the first case? And why doesn't it do the same in the second case? What's the meaning of this error message?
Upvotes: 1
Views: 169
Reputation: 29736
According to the documentation Entity Framework Code First Conventions:
Primary Key Convention
Code First infers that a property is a primary key if a property on a class is named “ID” (not case sensitive), or the class name followed by "ID". If the type of the primary key property is numeric or GUID it will be configured as an identity column.
Foreign key Convention
Any property with the same data type as the principal primary key property and with a name that follows one of the following formats represents a foreign key for the relationship: ‘’, ‘’, or ‘’. If multiple matches are found then precedence is given in the order listed above. Foreign key detection is not case sensitive. When a foreign key property is detected, Code First infers the multiplicity of the relationship based on the nullability of the foreign key. If the property is nullable then the relationship is registered as optional; otherwise the relationship is registered as required.
Upvotes: 0
Reputation: 5121
Set the parent for the child
var child = new Child { Name = "ch_1", Parent = parent }
you have 2 parents in the context with Id = 0 and the child has no reference to which it should be attached to. Non nullable type Int will get the default value of 0 when instantiating a new instance.
Upvotes: 1