我正在使用Entity Framework 6.2,代码优先。我有这两个类:
public class Agent
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int? AgentId { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
public int OfficeId { get; set; }
[ForeignKey("OfficeId")]
public virtual Office Office { get; set; }
}
和
public class Office
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int OfficeId { get; set; }
public string Agency { get; set; }
public string Branch { get; set; }
[InverseProperty("Office")]
public virtual ICollection<Agent> Agents { get; set; }
}
因此每个代理人都属于一个办公室(只有一个办公室)。相反,办公室可以包含许多代理商。
我的应用程序连接到Web API,后者通过代理和办公室向其提供XML数据(我使用 XDocument )。然后我用这些对象填充 DbContext ,并调用 dbContext.SaveChanges();
此时,我收到此错误:
“无法添加或更新子行:外键约束失败 (
fusion
。agent
,CONSTRAINTFK_agent_office_OfficeId
FOREIGN KEY (OfficeId
)REFERENCESoffice
(OfficeId
)ON DELETE CASCADE ON 更新CASCADE)“
听起来像EF正试图在办公室之前保存代理商。因此,当它将第一个代理写入数据库时,没有相应的办公室,并且事务失败。我会想象EF会找出正确的事物顺序(基于导航属性)并以正确的顺序保存东西?
现在,我需要指出的是,当我的应用程序将代理和办公室添加到DbContext时,它首先添加了代理,然后是办公室 - 这也许就是为什么EF也将它们插入到数据库中同样的顺序。不幸的是,当我的应用程序调用Web API时,API首先向代理发送带有代理的XML数据,然后是办公室。
如何让EF在代理商之前保存办公室?
答案 0 :(得分:1)
EF会根据导航属性确定正确的顺序。还有别的错。可能会出现一些问题。
您为什么使用[DatabaseGenerated(DatabaseGeneratedOption.None)]
?您是在创建和维护ID还是数据库?如果数据库不是您想要的[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
?
代理上也是可以为空的主键吗?那是对的吗?主键不能是可空的......
您不应该将[InverseProperty("Office")]
设置为正常的1对多关系。这可能会让EF感到困惑。