MVC2 RTM - 使用Entity Framework绑定复杂对象的模型

时间:2010-08-26 16:30:30

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

我是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);
        }

2 个答案:

答案 0 :(得分: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);
        }

答案 1 :(得分:1)

最终我找到了一个更优雅的解决方案,但从未回过头来发布它。这是 - 抱歉延迟:

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);

我正在从现实应用中转换此代码,所以我为任何错别字道歉。