当我改变关联时,是否必须手动设置外键属性? [英] Do I have to set foreign key properties manually when I change associations?

查看:141
本文介绍了当我改变关联时,是否必须手动设置外键属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从Linq-to SQL迁移到Entity Framework(4.4),使用数据库优先与DbContext。我想知道以下行为是否正常:

  using(var e = new AgendaEntities()){
var store = e.Stores.First();
var office = e.Offices.Create();
office.Store = store; //设置关联
Console.WriteLine(office.StoreID); //显示Guid.Empty,预期store.ID!
}

在L2S中,设置 Store 与实体的关联也会更新 StoreID 键。在EF中,似乎没有发生。这是不管实体是新的还是从上下文加载。



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



有没有我想要的东西,还是我现在应该手动保持外键同步?






解决方案编辑:
这被称为属性fixup,并且被生成的代理自动完成。但是,使用 DbContext 不再是这样。根据此连接问题,这是设计。


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


另一种方法是调用 DbContext.Entry(entity),它将同步该实体。这在本文中有所描述:关系和导航属性在同步FK和导航属性

解决方案

否。实体框架为您做这个。有关详细信息,请参阅关系和导航属性


通过为导航属性分配一个新对象。以下
代码创建课程与 部门之间的关系
如果对象附加到上下文, 课程 也将$ b​​ $ b添加到 department.Courses 集合,课程对象上的
对应的外键属性设置为
键属性值 部门




  • 课程.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 作为导航属性的外键商店


I'm migrating from Linq-to-SQL to Entity Framework (4.4), using Database First with a DbContext. I'm wondering whether the following behavior is normal:

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!
}

In L2S, setting the Store association to an entity would also update the StoreID key. In EF, this doesn't seem to be happening. This is regardless of whether the entities are new or loaded from the context.

When I SaveChanges, it saves correctly and the StoreID is updated to match office.ID, but why does this only happen after the save?

Is there something I'm missing, or am I now supposed to keep foreign keys in sync manually?


Solution Edit: This is called property fixup, and used to be done automatically by the generated proxies. However, with DbContext this is no longer the case. According to this Connect issue, this is by design.

Hello, The DbContext template actually doesn't generate classes that will be used as change tracking proxies - just lazy loading proxies (which don't do fix-up). We made this decision because change tracking proxies are complex and have a lot of nuances that can be very confusing to developers. If you want fix-up to occur before SaveChanges you can call myContext.ChangeTracker.DetectChanges. ~EF Team

An alternative is to call DbContext.Entry(entity), which will sync up the entity. This is described in this article: Relationships and Navigation Properties under "Synchronizing the changes between the FKs and Navigation properties"

解决方案

No. Entity framework does this for you. Read Relationships and Navigation Properties for more information.

By assigning a new object to a navigation property. The following code creates a relationship between a course and a department. If the objects are attached to the context, the course is also added to the department.Courses collection, and the corresponding foreign key property on the course object is set to the key property value of the department.

  • course.Department = department;

But as you observed, this only happens after you call SaveChanges or one of the other actions mentioned in the "Synchronizing the changes between the FKs and Navigation properties" portion of the document linked above.

If you are using POCO entities without proxies, you must make sure that the DetectChanges method is called to synchronize the related objects in the context. Note, that the following APIs automatically trigger a DetectChanges call.

  • DbSet.Add
  • DbSet.Find
  • DbSet.Remove
  • DbSet.Local
  • DbContext.SaveChanges
  • DbSet.Attach
  • DbContext.GetValidationErrors
  • DbContext.Entry
  • DbChangeTracker.Entries
  • Executing a LINQ query against a DbSet

If this is not happening at all, my guess is that you haven't properly defined StoreID as the foreign key of the navigation property Store.

这篇关于当我改变关联时,是否必须手动设置外键属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆