为什么Entity Framework假定该外键的值?

时间:2015-12-14 10:03:58

标签: c# entity-framework

我有以下型号。

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; }
}

在以下代码中,EF将父对象和子对象都插入到dbo.Child.ParentId字段引用dbo.Parent.Id的数据库中,即使从未设置child.ParentId属性。

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 

但是在下面的代码中,EF无法保存引发此异常的更改:

  

无法确定'TestEfProxy.Child_Parent'关系的主要结尾。多个添加的实体可能具有相同的主键。

代码:

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

为什么EF在第一种情况下决定child.ParentId引用parent.Id?为什么不在第二种情况下做同样的事情呢?这个错误信息的含义是什么?

2 个答案:

答案 0 :(得分:1)

设置孩子的父级

var child = new Child { Name = "ch_1", Parent = parent }

你在上下文中有2个父母,Id = 0,并且孩子没有引用它应该附加到哪个。实例化新实例时,非可空类型Int将获得默认值0。

答案 1 :(得分:0)

根据文件Entity Framework Code First Conventions

  

主要关键会议

     

Code First推断,如果某个类的属性名为“ID”(不区分大小写),或者类名后跟&#34;则属性是主键。 ID&#34; 即可。如果主键属性的类型是数字或GUID,则它将被配置为标识列。

     

外键公约

     

与主要主键属性具有相同数据类型且名称遵循以下格式之一的任何属性都表示关系的外键:'',''或''。如果找到多个匹配,则按上面列出的顺序给出优先级。外键检测不区分大小写。当检测到外键属性时,Code First根据外键的可为空性推断关系的多样性。如果属性可以为空,则将关系注册为可选;否则,关系会按要求注册。