【问题标题】:MVC2 RTM - model binding complex objects using Entity FrameworkMVC2 RTM - 使用实体框架模型绑定复杂对象
【发布时间】:2011-04-29 04:34:28
【问题描述】:

我是 MVC 的新手,我真的很挣扎于我认为它应该是一个非常常见的场景。我正在为我的模型对象使用 MVC2 RTM 和实体框架。

我的工作:

包含一组子对象的父对象的编辑视图。该表单显示父对象的所有可编辑字段,并遍历并显示所有关联子对象的所有可编辑字段(在同一视图中)。我能够成功处理控制器中的编辑操作,但是当我尝试将表单集合中的值绑定到 EF 模型对象时遇到问题。

问题:

在我的控制器函数中,当我调用 TryUpdateModel 并传递父对象时,出现以下错误:

“EntityCollection 已经被初始化。InitializeRelatedCollection 方法只能在对象图的反序列化过程中被调用来初始化一个新的 EntityCollection。”

我看到很多其他人发的帖子都在为类似问题而苦苦挣扎,但还没有找到解决方案。如果不构建自定义模型绑定器,这是不可能的吗?如果有人有一个可行的例子,我将不胜感激。出于某种原因,我能够遍历子集合并在子对象上成功执行 TryUpdateModel,但是当我在父对象上调用它时,会引发上述错误。理想情况下,我想为父级调用一次,然后从表单中更新整个对象树。

这是控制器代码:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection formValues)
        {
            EFEntities ef = new EFEntities();
            ParentObject parent = ef.ParentObjects.SingleOrDefault(p => p.ID == id);

            if (ModelState.IsValid)
            {
                int i = 0;
                foreach (child in parent.ChildObjects)
                {
                    //this works fine
                    TryUpdateModel(child, "ChildObjects[" + i + "]"); 
                    i++;
                }

                //this blows up
                if (TryUpdateModel(parent)) 
                {                    
                    ef.SaveChanges();
                    return RedirectToAction("Details", new { id = parent.ID });
                }
            }
            return View(parent);
        }

【问题讨论】:

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


    【解决方案1】:

    感谢这个问题,即使没有回答,它也给了我我的答案。我能找到的最好的办法是(使用你的例子):

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(int id, FormCollection formValues)
            {
                EFEntities ef = new EFEntities();
                ParentObject parent = ef.ParentObjects.SingleOrDefault(p => p.ID == id);
    
                if (ModelState.IsValid)
                {
                    int i = 0;
                    foreach (child in parent.ChildObjects)
                    {
                        //this works fine
                        TryUpdateModel(child, "ChildObjects[" + i + "]"); 
                        i++;
                    }
    
                    //exclude the collections and it won't blow up...
                    if (TryUpdateModel(parent, "Parent", null, new string[] {"ChildObjects"})) 
                    {                    
                        ef.SaveChanges();
                        return RedirectToAction("Details", new { id = parent.ID });
                    }
                }
                return View(parent);
            }
    

    【讨论】:

      【解决方案2】:

      最终我找到了一个更优雅的解决方案,但再也没有回来发布它。这是 - 抱歉耽搁了:

      if (ModelState.IsValid)
              {
                  if (TryUpdateModel(parent, new[] "prop1", "prop2", "prop3" })) //specify parent-only properties to include
                  {
                      if (TryUpdateModel(parent.ChildObjects, "ChildObjects"))
                      {
                          _ef.SaveChanges();
                          return RedirectToAction("Details", new { id = parent.ID })                    }
                  }
              }
              return View(parent);
      

      我正在将此代码从现实生活中的应用程序转换,因此对于任何拼写错误,我深表歉意。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-25
        • 2014-10-21
        相关资源
        最近更新 更多