EF6中如何更新通过Include加载的关联Address数据?
解决EF6中更新Include加载的关联Address数据问题
你的代码目前只更新了users表,是因为你只把User实体的状态标记为Modified,并且CurrentValues.SetValues只会处理主实体的属性,没有对关联的Address做状态跟踪和属性更新。下面给你几种可行的解决方案:
一、直接更新关联的Address实体(适用于Address已存在且仅需修改的场景)
首先注意:你用Include加载的MyUser已经被EF上下文跟踪了,所以db.Users.Attach(MyUser);这行是多余的,甚至可能引发异常,建议删掉。
修改后的代码如下:
var MyUser = db.Users.Include(b => b.Address) .Where(x => x.MISPAR_ZIHUY.Equals(123456)) .FirstOrDefault(); // 更新User自身的属性 db.Entry(MyUser).CurrentValues.SetValues(MyNewUser); // 处理关联的Address更新 if (MyNewUser.Address != null && MyUser.Address != null) { // 把MyNewUser中Address的属性值同步到已跟踪的MyUser.Address db.Entry(MyUser.Address).CurrentValues.SetValues(MyNewUser.Address); // 标记Address实体为已修改,EF会生成对应的UPDATE语句 db.Entry(MyUser.Address).State = EntityState.Modified; } db.SaveChanges();
二、处理Address可能新增/删除的复杂场景
如果你的业务中存在Address可能被新增(比如原来没有Address现在添加)或者删除的情况,可以这样处理:
var MyUser = db.Users.Include(b => b.Address) .Where(x => x.MISPAR_ZIHUY.Equals(123456)) .FirstOrDefault(); // 更新User属性 db.Entry(MyUser).CurrentValues.SetValues(MyNewUser); if (MyNewUser.Address != null) { if (MyUser.Address == null) { // 原来没有Address,现在新增,直接添加到导航属性 MyUser.Address = MyNewUser.Address; db.Entry(MyUser.Address).State = EntityState.Added; } else { // 已有Address,更新属性并标记为修改 db.Entry(MyUser.Address).CurrentValues.SetValues(MyNewUser.Address); db.Entry(MyUser.Address).State = EntityState.Modified; } } else { // MyNewUser没有Address,说明要删除原有的Address if (MyUser.Address != null) { db.Addresses.Remove(MyUser.Address); } } db.SaveChanges();
关键知识点说明
- EF上下文只会自动跟踪直接标记为Modified或者**属性被修改(在上下文跟踪期间)**的实体,关联实体不会自动继承主实体的状态。
CurrentValues.SetValues方法只会复制同类型实体的标量属性,不会处理导航属性,所以必须单独处理Address。- 如果你的
User和Address的关联关系配置不正确(比如没有正确设置外键),可能会导致更新失败,确保Code First的Fluent API或者Data Annotation配置正确(比如[ForeignKey]特性,或者modelBuilder.Entity<User>().HasRequired(u => u.Address).WithRequiredPrincipal(a => a.User)这类配置)。
内容的提问来源于stack exchange,提问作者user1012506
相关产品推荐
相关产品推荐

