我有以下型号:
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值更改为其他值然后我得到错误:
发生了参照完整性约束违规:属性 定义引用约束的值不一致 在关系中的主要和依赖对象之间。
答案 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不知道哪个代表正确的关系:外键属性值或导航属性值?这种歧义导致例外。