C# 调用DetectChanges()时不会自动更新外键属性

C# 调用DetectChanges()时不会自动更新外键属性,c#,entity-framework-6,dbcontext,C#,Entity Framework 6,Dbcontext,我有一个非常基本的示例C#程序(简化为更复杂的程序),它使用EF6和DbContext,包含两个类: Teacher 1...n Lesson 有一个FK约束,当删除教师实例时,该约束会将课程中的FK列设置为null 示例程序: using (var context = new EFTestEntities()) { // An instance of Teacher (named teacher) and Lesson (named lesson) are created,

我有一个非常基本的示例C#程序(简化为更复杂的程序),它使用EF6和DbContext,包含两个类:

Teacher   1...n   Lesson
有一个FK约束,当删除教师实例时,该约束会将课程中的FK列设置为null

示例程序:

using (var context = new EFTestEntities()) {
  // An instance of Teacher (named teacher) and Lesson (named lesson) are created,
  // both are added to the context and context.SaveChanges() is called.

  // teacher is assigned to lesson and DetectChanges() is called.

  using (var context2 = new EFTestEntities()) {
    // Get teacher from the DB, delete it and save the changes.
  }

  // Because here I know that teacher could have been changed or deleted,
  // I refresh it from the database using ObjectContext.Refresh(RefreshMode.StoreWins).
  // But when SaveChanges() is called,
  // an SqlException concerning FK constraint violation is thrown.
}
调试时,我看到:

lesson --> teacher (Navigation Property): null (correct)
lesson --> teacher (Foreign Key Property): ID of deleted teacher (incorrect, should be null)
因为课程中的外键属性仍然指向已删除的教师,所以SqlException是有意义的

但是为什么外键属性仍然指向已删除的教师?调用
DetectChanges()
时,应将其设置为
null

意见:

  • 不调用
    Refresh()
    并手动将导航属性设置为null:外键按预期更新。因此,
    Refresh()
    调用一定与此问题有关
  • 调用
    DbEntityEntry的
    Reload()
    ,而不是
    ObjectContext的
    Refresh()
    ,会导致相同的问题
  • 不仅刷新教师,还刷新课程:使
    DetectChanges()
    按预期更新外键。但这样一来,已经对课程进行的所有更改都将丢失

如果删除了教师,但仍为其分配了一节课…,当您尝试保存更改时,我甚至不确定它会是什么,刷新后教师实体的“状态”是什么()以及它有什么值。另一方面,以这种方式与事物互动似乎很奇怪。您不能使用相同的数据库上下文吗?听起来你有脱节的代码,这是一个消费的问题,应该改变,而不是试图做刷新更新陈旧的上下文意识问题。谢谢你的回答。删除教师后,课程中的FK列将设置为null。我在我的问题中加了这个。在Refresh()之后,状态保持不变。然后,除了外键属性之外,它还有来自数据库的值。但是,当调用DetectChanges()时,应该会对其进行更新。但事实并非如此。不,我不能使用相同的上下文。真正的程序要复杂得多,这是不可能的。我的猜测是,您需要再次添加它…,但这听起来像是您在以后的过程中会遇到其他问题。分离课程实例,重新附加它并将其状态设置为“修改”:确实会使
DetectChanges()
再次按预期更新外键。但每次使用
Refresh()
方法时,我都需要这样做。如果教师被删除,并且仍然有一节课分配给它…,当您尝试保存更改时,我甚至不确定它会是什么,它说教师实体在Refresh()后处于什么“状态”以及它有什么值。另一方面,以这种方式与事物互动似乎很奇怪。您不能使用相同的数据库上下文吗?听起来你有脱节的代码,这是一个消费的问题,应该改变,而不是试图做刷新更新陈旧的上下文意识问题。谢谢你的回答。删除教师后,课程中的FK列将设置为null。我在我的问题中加了这个。在Refresh()之后,状态保持不变。然后,除了外键属性之外,它还有来自数据库的值。但是,当调用DetectChanges()时,应该会对其进行更新。但事实并非如此。不,我不能使用相同的上下文。真正的程序要复杂得多,这是不可能的。我的猜测是,您需要再次添加它…,但这听起来像是您在以后的过程中会遇到其他问题。分离课程实例,重新附加它并将其状态设置为“修改”:确实会使
DetectChanges()
再次按预期更新外键。但是每次使用
Refresh()
方法时,我都需要这样做。