简体   繁体   中英

Why Entity Framework assumes a value for that foreign key?

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?

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM