【问题标题】:Do I have to set foreign key properties manually when I change associations?更改关联时是否必须手动设置外键属性?
【发布时间】:2013-03-21 17:02:29
【问题描述】:

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

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 不再是这种情况。根据this Connect issue,这是设计使然。

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

另一种方法是调用DbContext.Entry(entity),这将同步实体。本文对此进行了描述:Relationships and Navigation Properties 在“同步 FK 和导航属性之间的更改”下

【问题讨论】:

  • 很难理解没有更多人欣赏这个解决方案。没有人以这种方式使用 dbcontext?
  • 就个人而言,我现在只是在更改关联时手动设置键。修复是一个不错的选择,但经过一番思考,期望 POCO 无论如何都这样做没有多大意义。无论如何,任何改变关联的操作都应该在某个领域层方法中抽象出来,所以最终它并没有我想象的那么刺耳。
  • 我是 dbEntityValidations 的“盲目”实体,我的所有业务规则都能够将实体暴露给 UI 层,至少对于“简单”实体而言。我用'entry.related'但detectChanges方法处理延迟加载相关实体。感谢您的帖子和解决方案。
  • 修复通过改变外键来改变现有实体之间的关系。但是,对于不是代理的新实体,修复无法正常工作。

标签: entity-framework entity-framework-4


【解决方案1】:

没有。实体框架会为你做这件事。阅读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的外键。

【讨论】:

  • 我认为在您链接的文章底部的“同步 FK 和导航属性之间的更改”中描述了正在发生的事情。调用 e.Entry(office) 会同步 ID。但是,我可以在调试器中看到正在创建代理,所以它应该工作......
  • @IliaJerebtsov 啊,正确。我最初误读了你的问题。我以为你说这根本没有发生。
  • 谢谢,我已经想通了,显然 DbContext API 中没有修复是设计使然。
猜你喜欢
  • 2014-09-11
  • 2011-06-02
  • 1970-01-01
  • 2018-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-06
相关资源
最近更新 更多