我已经苦苦挣扎了一段时间,但在Stack Overflow上找不到解决方案。
我有一个使用Entity Framework、Repository和Unit of Work模式的MVC应用程序。最近我从使用网络数据库(Sql Server 2008 R2,在那里问题似乎不存在)转向使用本地数据库,并开始使用Entity Framework迁移来与另一个开发人员合作,以便我们不通过对模型进行更改来互相影响。
我的模型看起来像这样:
[Table("Student")]
public class Student
{
[Key]
public int Id { get; set; }
<... other fields ...>
[Required(ErrorMessage = "A student type is required")]
public int StudentTypeId { get; set; }
[Required(ErrorMessage = "A student status is required")]
public int StudentStatusId { get; set; }
[ForeignKey("StudentTypeId")]
public virtual StudentType StudentType { get; set; }
[ForeignKey("StudentStatusId")]
public virtual StudentStatus StudentStatus { get; set; }
}
每当我尝试更新学生的StudentStatus属性时,就会出现以下异常:
"The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: A referential integrity constraint violation occurred: The property value(s) of 'StudentStatus.Id' on one end of a relationship do not match the property value(s) of 'Student.StudentStatusId' on the other end."
我尝试在保存更改之前将导航属性重置为null,但问题仍然存在。
student.StudentStatus = null;
student.StudentStatusId = 26;
_studentRepository.Update(student);
_unitOfWork.Commit();
我尝试检索特定的学生状态对象:
var studentStatus = _studentStatusRepository.GetById(26);
student.StudentStatusId = 26;
student.StudentStatus = studentStatus;
_studentRepository.Update(student);
_unitOfWork.Commit();
但是每次尝试执行DataContext.SaveChanges()时都会抛出相同的异常。
我可以更新StudentType(这是完全相同类型的关系和类),没有任何问题。
Update方法的实现:
public virtual void Update(T entity)
{
try
{
DataContext.Entry(entity).State = EntityState.Modified;
}
catch (Exception exception)
{
throw new EntityException(string.Format("Failed to update entity '{0}'", typeof(T).Name), exception);
}
}
我注意到EF Migrations在数据库中创建了更多的索引,与我以前的网络数据库相比。但是我已经手动删除了它们(并不是因为我认为它们一定是问题所在)。我尝试比较两个数据库中的关系,看起来一切都是一样的。
我知道如果没有提供更多信息,很难指出可能出现什么问题,但还有什么其他可能导致这个问题的原因呢?
编辑(添加了StudentStatus类和相应的StudentStatusType)。
[Table("StudentStatus")]
public class StudentStatus
{
[Key]
public int Id { get; set; }
[Required(ErrorMessage = "Student status name is required")]
[MaxLength(50, ErrorMessage = "Student status name cannot be longer than 50 characters")]
public string Name { get; set; }
public int StudentStatusTypeId { get; set; }
[ForeignKey("StudentStatusTypeId")]
public virtual StudentStatusType StudentStatusType { get; set; }
}
[Table("StudentStatusType")]
public class StudentStatusType
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
编辑2
我忘记提到我在存储库级别启用了数据库日志记录,以查看Entity Framework执行的SQL查询:
DataContext.Database.Log = s => Debug.WriteLine(s);
结果如下:
UPDATE [dbo].[Student]
SET <... some parameters ...>, [StudentStatusId] = @10, <... some parameters ...>
WHERE ([Id] = @14)
UPDATE [dbo].[Student]
SET <... some parameters ...>, [StudentStatusId] = @10, <... some parameters ...>
WHERE ([Id] = @14)
<... some parameters ...>
-- @10: '25' (Type = Int32)
-- @10: '25' (Type = Int32)
<... some parameters ...>
-- Executing at 12/01/2015 12:30:41 +00:00
-- Executing at 12/01/2015 12:30:41 +00:00
-- Completed in 0 ms with result: 1
-- Completed in 0 ms with result: 1
那么为什么EF试图插入值25,即使我明确指定它为26?这是否导致了潜在的问题?此外,为什么会有两个更新语句而不是一个?
StudentStatus
类吗? - Corey Adler[ForeignKey(“StudentStatusType”)] public int StudentStatusTypeId {get; set;}
,并在其下面添加一个类型为StudentStatusType
的虚属性。不知道这是否重要。 - Allmighty