【问题标题】:Error in Entity Framework Saving with Child Entity使用子实体保存实体框架时出错
【发布时间】:2012-11-14 12:48:45
【问题描述】:

我有以下型号:

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 值更改为其他值,然后我收到错误:

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

【问题讨论】:

  • 你能发布你用来更新清洁值的整个方法吗?可能发生的情况是,当作业对象未附加到上下文时,您正在附加新的清洁器对象。因此,FK 没有更新,因为它们不是管理它的上下文,并且当您将它附加到上下文时,由于它不正确,您会收到错误消息。您可以在进行更新之前将其附加到上下文中,或者更新您的 FK 值。
  • 有一个 MVC 页面,它使用 ajax 和敲除来检索作业对象,并且更清洁的 int 值被更改并 PUT 到上面的保存方法。有没有办法在为 FK 手动保存代码之前更新对象。

标签: entity-framework


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 2020-11-28
    • 1970-01-01
    相关资源
    最近更新 更多