实体框架似乎在父对象之前保存子对象
我使用的是实体框架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,该API用代理和办公室为其提供XML数据(为此,我使用XDocument)。然后用这些对象填充我的DbContext,并调用dbContext.SaveChanges();
在这一点上,我得到这个错误:
"Cannot add or update a child row: a foreign key constraint fails (
fusion
.agent
, CONSTRAINTFK_agent_office_OfficeId
FOREIGN KEY (OfficeId
) REFERENCESoffice
(OfficeId
) ON DELETE CASCADE ON UPDATE CASCADE)"
像EF试图在办公室之前保存代理声音给我。所以当它将第一个代理写入数据库时,就没有相应的办公室,事务就失败了。我会想象EF会找出事物的正确顺序(基于导航属性),并按正确的顺序保存东西?
现在,我需要指出的是,当我的应用程序将代理和办公室添加到DbContext中时,它首先添加代理,然后添加代理 - 这也许是EF为什么还将它们插入到数据库中相同的顺序。不幸的是,当我的应用程序调用Web API时,API会先向我发送带有代理的XML数据,然后再向我发送办公室数据。
如何让EF在代理商之前保存办公室?
EF确实根据导航属性计算出正确的顺序。还有其他的错误。有几件事可能是这个问题。
你为什么用[DatabaseGenerated(DatabaseGeneratedOption.None)]
?你正在创建和维护ID还是数据库?如果它的数据库不想要[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
?
代理上的一个可为空的主键?那是对的吗?主键不能/不应该为空...
您不需要设置[InverseProperty("Office")]
为正常的1对多关系。这可能会令EF令人困惑。
谢谢Gareth,您的回复指出我的方向是正确的 – user1900799
如果Agent表引用了Office表的主键,则EF将首先创建Office行,以便将其ID插入到新的Agent行中。 EF不仅可以查看导航属性,还可以从数据库映射中推断出它们是如何导出的。 –
您可以将代码添加到上下文中吗? – Mats391
当你想添加新的“代理和办公室”或者当你想添加一个代理时,你有这个问题吗? –