【问题标题】:EF, MVC, Model binding, and Navigation propertiesEF、MVC、模型绑定和导航属性
【发布时间】:2012-08-31 16:51:47
【问题描述】:

我正在使用 EF5 Code First :

public class Scenario
{
    public int Id { get; set; }
    public  IList<Client> Clients { get; set; }
}
public class Client
{
    public int Id { get; set; }
    public string Name {get;set;}
    public int VisibilityNumber{ get; set; }
}

我直接将场景对象发送到视图(MVC4,不使用视图模型类 - 可能是一个错误?,但管道代码少了很多)。在我看来,我对 Scenario.Id 使用 HiddenFor,并使用 for 循环为每个客户端 VisibilityNumber 显示一个 EditFor。

这是控制器:

[HttpPost]
public ActionResult Edit(int id, FormCollection formValues)
{     
if (ModelState.IsValid)
    {
        Scenario scen=GetScenarioFromDB(id);
        TryUpdateModel(scen,formValues);
        if (ModelState.IsValid)
           SaveToDb(scen);
    }
}

在 TryUpdateModel 之后,对于每个 Clients 对象(从 DB 中正确加载):

  • VisibilityNumber 设置正确
  • id设置为0,当然是坏事
  • 名称设置为空

查看 MVC 源代码(DefaultModelBinder/UpdateCollection)后,我可以看到在绑定到集合时,总是会创建新项目。 如果我不能解决这个问题,我想我将使用 viewModel 和 AutoMapper。我假设 MVC 团队想强迫我们使用 viewModel,而不是直接发送 EF 对象。

【问题讨论】:

    标签: asp.net-mvc entity-framework model-binding


    【解决方案1】:

    您不应该在更新中从数据库中获取scenario。相反,您应该获取绑定模型,将其附加(如果已编辑)或将其添加(如果新)到上下文,然后保存更改。这是一种称为“断开连接的实体”的常见场景(实际上,您确实有这种情况,因为您的模型在发送到客户端时断开连接,然后返回也断开连接)。

    【讨论】:

    • 我不能这样做,因为我的绑定模型不包含我所有的数据库字段。例如,Name 属性只显示在视图上,所以它不在绑定模型中。我知道我可以使用隐藏字段来解决这个问题,但这似乎是错误的。 UpdateModel 是为我的场景制作的(只要我没有导航属性就可以工作)
    • @Guillaume 这也包含在同一个用例中。您只需将适当的属性显式标记为已更改。
    • 好的!我只是不明白如何在不混合太多 Web 和数据层的情况下做到这一点:目前,我的 MVC 项目不知道数据上下文。我也不想在我的数据层中创建特定于 Web 的方法(以告知哪些“适当的属性”已更改)。还是谢谢
    • 我首先使用代码,常规 POCO,只有几个注释,所以我不确定这是否可以被视为数据模型。唯一的数据模型入侵是一些注释,我可以通过流畅的路线走得更远。
    【解决方案2】:
    1. 我“修复”了 DefaultModelBinder/UpdateCollection 以便它可以与我的用例一起使用:当绑定在导航属性中向下钻取时,它使用当前对象作为模型(这很简单,因为我只是在做修改,没有插入或删除):我可以获取 DefaultModel 源代码,将我的修复放入其中,并将其用作自定义模型绑定器。这很有趣,但有点肮脏而且过头了。
    2. 但我认为最好的方法是使用特定的 ViewModel,仅使用可编辑的属性,并使用 AutoMap 将其映射到我的 EF 层次结构。但是:它有创建子对象集合的相同问题。
    3. 最后,我只是在我的视图模型和我的 EF 层次结构之间进行了一些手动映射:我几乎可以肯定我可以自动执行一些操作,这可以检测子项是否已被修改、插入或删除(因为每个项目都有一个 [key] 属性,但我没有时间预算来实施它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-21
      • 1970-01-01
      • 2019-08-12
      相关资源
      最近更新 更多