MVC 3 Master / Detail UpdateModel插入新的详细记录而不是更新现有记录

时间:2011-02-06 20:41:19

标签: asp.net-mvc master-detail updatemodel

好的,我已经阅读了Phil Haack的article关于绑定到列表的内容,并且我已经在一个视图上正常工作了。但是当我从主记录中做到这一点时我会陷入困境。

我为这个对象提供了一个非常简单的表单

public class Master
{
    public int ID { get; set; }
    public string MasterTitle { get; set; }
    public virtual IList<Detail> Details { get; set; }
}

public class Detail
{
    public int ID { get; set; }
    public string DetailName { get; set; }
    public virtual Master Master { get; set; }
}

表单集合带有预期的前缀:

    [0] ""  
    [1] "ID"    
    [2] "MasterTitle"   
    [3] "Details[0].ID" 
    [4] "Details[0]"    
    [5] "Details"   
    [6] "Details[0].DetailName" 
    [7] "Details[1].ID" 
    [8] "Details[1]"    
    [9] "Details[1].DetailName" string

Controller.UpdateModel(master)正确绑定所有属性。但是,当我调用dbContext.SaveChanges时,它会从sql profiler(伪造代码)发出以下sql

update detail1 set masterID = null
update detail2 set masterID = null
update master set masterName = 'newname'
insert detail1 ...
insert detail2 ...

我有一个可行的工作,但它非常hackish我目前没有匹配键,所以它依赖于以正确的顺序返回的一切。另外,我必须包括我想要更新的所有字段。

    public ActionResult Edit(FormCollection collection)
    {
        try
        {
            using (var ctx = new PlayContext())
            {
                var id = int.Parse(collection["ID"]);
                Master master = ctx.Master.Find(id);

                UpdateModel(master, new [] {"MasterTitle"});
                for (int i = 0; i < master.details.Count; i++)
                {
                    UpdateModel(master.details[i], "Details[" + i + "]", new[] { "DetailName" });
                }

                ctx.SaveChanges();
                return View(master);
            }
        }
        catch (Exception e)
        {
            ModelState.AddModelError("", e);
        }
        return View();
    }

我感觉UpdateModel以某种方式删除并重新添加了孩子。

有没有其他人让这个工作?当然,我可以自己动手并解析索引的字段名称,但我非常接近!

1 个答案:

答案 0 :(得分:1)

它应该工作 - 我没有在MVC2中使用类似代码的任何问题。

我担心这条线路:     [5]“详情”

它的详细信息是什么?我希望这可能导致问题 - 不完全确定模型绑定器在MVC 3中是如何工作的,但我希望这一行会导致它将Details集合设置为NULL。

您不必依赖于按特定顺序返回的字段 - 绑定器将被设计为以任何顺序处理它们。