实体框架似乎是在父对象之前保存子对象

时间:2017-02-15 08:31:03

标签: c# .net entity-framework entity-framework-6 dbcontext

我正在使用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();

此时,我收到此错误:

  

“无法添加或更新子行:外键约束失败   (fusionagent,CONSTRAINT FK_agent_office_OfficeId FOREIGN KEY   (OfficeId)REFERENCES officeOfficeId)ON DELETE CASCADE ON   更新CASCADE)“

听起来像EF正试图在办公室之前保存代理商。因此,当它将第一个代理写入数据库时​​,没有相应的办公室,并且事务失败。我会想象EF会找出正确的事物顺序(基于导航属性)并以正确的顺序保存东西?

现在,我需要指出的是,当我的应用程序将代理和​​办公室添加到DbContext时,它首先添加了代理,然后是办公室 - 这也许就是为什么EF也将它们插入到数据库中同样的顺序。不幸的是,当我的应用程序调用Web API时,API首先向代理发送带有代理的XML数据,然后是办公室。

如何让EF在代理商之前保存办公室?

1 个答案:

答案 0 :(得分:1)

EF会根据导航属性确定正确的顺序。还有别的错。可能会出现一些问题。

您为什么使用[DatabaseGenerated(DatabaseGeneratedOption.None)]?您是在创建和维护ID还是数据库?如果数据库不是您想要的[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

代理上也是可以为空的主键吗?那是对的吗?主键不能是可空的......

您不应该将[InverseProperty("Office")]设置为正常的1对多关系。这可能会让EF感到困惑。