【问题标题】:Navigation Property not being updated on db.SaveChanges()导航属性未在 db.SaveChanges() 上更新
【发布时间】:2017-12-15 14:34:26
【问题描述】:

我有一个 Edit 控制器方法,它从 Edit 视图中获取 Tool

Tool 模型包含一个名为Holder 的导航属性MobileUser,它还包含一个字符串HolderName,用于在视图中设置一个持有者。

在控制器方法中,我通过使用Tool.HolderName == MobileUser.Name 获取用户来设置MobileUser,但是在调用db.SaveChanges() 之后,MobileUser 导航属性在数据库中没有变化。

我的代码:

ToolsController.Edit(工具工具):

        int id = db.MobileUsers.Single(x => x.Name == tool.HolderName).Id;
        tool.Holder = db.MobileUsers.Find(id);

        if (ModelState.IsValid)
        {
            db.Entry(tool).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(tool);

Tool类中的Holder导航属性:

    public virtual MobileUser Holder { get; set; }

【问题讨论】:

  • 您是否尝试过将条目和保存包含在 try catch 中并查看是否抛出异常?
  • 您说您正在从表单中获取工具作为模型,但我认为它应该附加到上下文中
  • @MichaelStaples 我做了,没有抛出异常。
  • @Neir0 我尝试在保存前附加,但仍然没有骰子。
  • 你能告诉我们你是如何配置它们之间的关系的吗?当您使用属性而不是外键时,这是一个常见问题,特别是在断开连接的情况下。您是否也在调用保存更改之前从数据库中获取工具?

标签: c# asp.net asp.net-mvc entity-framework navigation-properties


【解决方案1】:

首先,不要在您的控制器语音中使用实体模型(使用 ViewModel),其次是展示您的模型。 IAC,试试这个:

[HttpPost]
public ActionResult Edit(Tool tool):

    if (ModelState.IsValid)
    {
        // If you want to update fields in tool.Holder, do something like this:
        var newHolder = tool.Holder;  // save changes from view.
        // Fetch the current Holder from database
        tool.Holder = db.MobileUsers.Single(x => x.Name == tool.HolderName);
        // Replace the changed properties. Many ways to do this. I like Automapper.
        tool.Holder.Field1 = newHolder.Field1;
        tool.Holder.Field2 = newHolder.Field2;
        // etc.

        db.Entry(tool).State = EntityState.Modified;
        // Below not needed since you getched it into the context
        // db.Entry(tool.Holder).State = EntityState.Modified;  // Need to set child state as well
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(tool);
}

在 ViewModel 场景中,您的 POST 将获取工具和支架,将更改映射并保存,而不会暴露您的整个实体。

【讨论】:

  • 感谢您的回复。我也更改了子模型的状态,但它仍然不起作用。
  • 您期望哪些变化不会发生?
  • tool.Holder 仍然存在。数据库并没有真正保存所做的更改。
  • 对 Holder 对象的更改不会与您显示的代码一起保留,因为您是从数据库中获取它,而不是像在 ViewModel 场景中那样将更改映射回。但是,您应该看到从 Tool 到 Holder(旧版本)的关系。见编辑。
  • 也许我不清楚我想要达到的目标。我只是想更新tool.Holder,而不是编辑对象本身。例如,如果有 2 个持有人 Viggo 和 Steve,而 Steve 是相关工具的当前持有人,我想将持有人更改为 Viggo。我不是想改变史蒂夫的属性。谢谢你对我的耐心。
【解决方案2】:

我最终放弃并改用了 GraphDiff。效果很好,如果以后有人遇到这个问题,我推荐它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-03
    • 1970-01-01
    • 2013-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    相关资源
    最近更新 更多