使用子实体保存实体框架时出错

时间:2012-11-14 12:48:45

标签: entity-framework

我有以下型号:

public class Job
{
    [Key]
    public int JobID { get; set; }
    public string Status { get; set; }
    public DateTime JobDate { get; set; }
    public string JobTitle { get; set; }
    public int? Cleaner { get; set; }
    public int? Client { get; set; }
    public int EstTime { get; set; }

    public virtual Client ClientInfo { get; set; }
    public virtual Valeter ValeterInfo { get; set; }
}

这在OnModelCreating:

// Relationship Job -> Valeter
        modelBuilder.Entity<Job>()
            .HasOptional<Valeter>(u => u.ValeterInfo)
            .WithMany()
            .HasForeignKey(e => e.Cleaner);

(注意:它使用的是现有数据库)。当我尝试执行以下操作时:

if (ModelState.IsValid)
{
   db.Entry(job).State = EntityState.Modified;
   db.SaveChanges();
}

它通常工作正常除非我将Cleaner值更改为其他值然后我得到错误:

  

发生了参照完整性约束违规:属性   定义引用约束的值不一致   在关系中的主要和依赖对象之间。

1 个答案:

答案 0 :(得分:2)

如果job.ValeterInfo != null job.ValeterInfo.ValeterId != job.Cleaner,通常会发生此异常。因此,最简单的解决方案是在将null附加到上下文之前将导航属性设置为job

if (ModelState.IsValid)
{
    job.ValeterInfo = null;
    db.Entry(job).State = EntityState.Modified;
    db.SaveChanges();
}

这看起来有点奇怪,就像黑客一样。但问题是,当您将数据发布到控制器操作时job.ValeterInfo不是null的原因。当您将job的状态设置为Modified时,您只更新作业的标量属性(包括Cleaner),但不更新job.ValeterInfo的任何属性或任何关系。因此,您首先不需要将job.ValeterInfo属性发送到服务器。

无论如何,您有一个不一致的地方:FK job.Cleaner已更改,但相关实体job.ValeterInfo(尤其是其主键属性ValeterId)未更改。 EF不知道哪个代表正确的关系:外键属性值或导航属性值?这种歧义导致例外。