首页 文章

MVC3 - 如何将新创建的子对象链接到其父对象?

提问于
浏览
3

我是MVC的完全新手,似乎无法理解一个非常基本的概念 .

我有一个父对象,它包含一个子对象的集合 . 我想创建一个新的子对象,并将其链接到父对象,通过EF4保存在数据库中

public class Parent
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public virtual List<Child> Children { get; set; }
    }

到目前为止,我的基本应用程序中发生了什么 . 我的用户转到显示父对象详细信息的页面,其中包含当前子项的列表 . 该页面上还有一个链接可添加新的孩子 . 该链接指向子控制器上的创建操作,传递父ID,父ID又显示视图以创建新子项 . 这就是我被困住的地方 . 我不知道如何持久保存提供的父ID,以便当我单击Save时,我可以检索该父对象并将我的新子对象添加到其集合中 .

我可能完全以错误的方式接近这个,但我似乎找不到任何关于如何向父项添加新子项的基本教程,考虑到它的常见情况,这很奇怪 .

任何帮助真的很感激!

非常感谢格里

[Update 1]

我有两个CreateChild操作,最初由MVC生成,然后由我自己修改 . 我只能通过观察他们看到他们没有做我需要的东西,但我完全不确定他们需要改变的方式 . 具体来说,我将父ID存储在ViewBag中,但是在对Create操作的调用之间,它会丢失,因此在调用第二个Create以将新子项持久保存到数据库时不可用 .

``
`public ActionResult Create(int parentId)
{
Parent parent = db.Parents.Find(parentId);
ViewBag.ParentId = parent.Id;
return View();
}

[HttpPost]
public ActionResult Create(Child child)
{
if (ModelState.IsValid)
{
Parent parent = db.Parents.Find(ViewBag.ParentId);
parent.Children.Add(child);
db.Children.Add(child);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(child);
}`
``

再次感谢格里

2 回答

  • 4

    当您将ParentId传递给add子操作时,看起来您正在使用route参数执行此操作 .

    而不是将其存储在ViewBag中,将其写为子表单中的隐藏字段 . 然后,当有人提交表单时,ParentId将被提交给您的HttpPost操作方法 .

    您可以通过在Parent viewmodel上创建ParentId属性来完成此操作 .

    public class Child
    {
        public int ParentId { get; set; }
    }
    
    public ActionResult Create(int parentId)
    {
        Parent parent = db.Parents.Find(parentId);
        var model = new Child { ParentId = parent.Id };
        return View(model);
    }
    

    在您的视图中,渲染如下:

    @Html.HiddenFor(m => m.ParentId)
    

    然后,在你的HttpPost期间,Child将已经包含ParentId - 默认的模型 Binders 将从表单上的隐藏字段中获取它 .

    [HttpPost]
    public ActionResult Create(Child child)
    {
        if (ModelState.IsValid)
        {
            Parent parent = db.Parents.Find(child.ParentId);
            parent.Children.Add(child);
            db.Children.Add(child); // don't think you need this line
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(child);
    }
    

    Update after posting answer

    查看您的HttpPost代码,将子项添加到数据库两次可能不正确 . 如果您使用的是EF 4.1或4.2,我很确定这是不正确的,但我不确定以前的EF版本 . 将子项添加到parent.Children集合应该足够了 - 我认为您不应该将它添加到db.Children集合中 .

  • 3

    ViewBag 不是 ViewState (ASP.NET MVC没有任何内置的等效于ASP.NET WebForms ViewState) - 它不会在调用之间保持 ParentId . 它只允许您通过ParentId查看(在您的第一个操作中),以便您可以将其存储在隐藏字段中 .

相关问题