更改关联时是否必须手动设置外键属性?

时间:2013-03-21 17:02:29

标签: entity-framework entity-framework-4

我正在使用Database First和DbContext从Linq-to-SQL迁移到Entity Framework(4.4)。我想知道以下行为是否正常:

using (var e = new AgendaEntities()) {
    var store = e.Stores.First();
    var office = e.Offices.Create();
    office.Store = store; // Set association
    Console.WriteLine(office.StoreID); // shows Guid.Empty, expected store.ID!
}

在L2S中,将Store关联设置为实体也会更新StoreID密钥。在EF中,这似乎并没有发生。这与实体是新的还是从上下文加载无关。

当我SaveChanges时,它会正确保存并且StoreID会更新以匹配office.ID,但为什么这只会在保存后发生?

我有什么遗漏,或者我现在应该手动保持外键同步吗?


解决方案编辑: 这称为属性修正,过去由生成的代理自动完成。但是,DbContext不再是这种情况。根据{{​​3}},这是设计的。

  

您好,    DbContext模板实际上不生成将用作更改跟踪代理的类 - 只是延迟加载代理(不执行修复)。我们做出这个决定是因为更改跟踪代理很复杂,并且有许多细微差别,这对开发人员来说可能非常混乱。    如果要在SaveChanges之前进行修复,可以调用myContext.ChangeTracker.DetectChanges。    ~EF团队

另一种方法是调用DbContext.Entry(entity),它将同步实体。本文描述了这一点:“同步FK和导航属性之间的更改”下的this Connect issue

1 个答案:

答案 0 :(得分:6)

没有。实体框架为您完成此任务。请阅读Relationships and Navigation Properties以获取更多信息。

  

通过将新对象分配给导航属性。下列   代码会在课程和 department 之间创建关系。   如果对象附加到上下文,则 course 也是   添加到 department.Courses 集合,以及   将课程对象上对应的外键属性设置为    department 的关键属性值。

     
      
  • course.Department = department;
  •   

但是正如您所观察到的,这只发生在您调用SaveChanges或上面链接的文档“同步FK和导航属性之间的更改”部分中提到的其他操作之后。

  

如果您使用没有代理的POCO实体,则必须确保   调用DetectChanges方法来同步相关的   上下文中的对象。请注意,以下API自动生成   触发DetectChanges调用。

     
      
  • DbSet.Add
  •   
  • DbSet.Find
  •   
  • DbSet.Remove
  •   
  • DbSet.Local
  •   
  • DbContext.SaveChanges
  •   
  • DbSet.Attach
  •   
  • DbContext.GetValidationErrors
  •   
  • DbContext.Entry
  •   
  • DbChangeTracker.Entries
  •   
  • 对DbSet执行LINQ查询
  •   

如果没有发生,我的猜测是你没有正确定义StoreID作为导航属性Store的外键。