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

发布于 2024-10-16 16:40:27 字数 2055 浏览 6 评论 0原文

好的,我已阅读 Phil Haack 的文章 绑定到列表,我在一个视图上工作得很好。但是当我在主记录上进行操作时,我遇到了困难。

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

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 ...

我有一个可行的解决方案,但它非常黑客,而且我目前没有匹配密钥,因此它依赖于返回的所有内容正确的顺序。另外,我必须包含我想要更新的所有字段。

    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 正在以某种方式删除并重新添加子项。

还有其他人让这个工作吗?当然,我可以认输并自己解析索引字段名称,但我已经很接近了!

Ok, I've read Phil Haack's article on binding to a list and I've got that working fine on one view. But what I'm stuck when doing it off a master record.

I've got a really simple form for this object

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

The form collection comes back with the expected prefixes:

    [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

And the Controller.UpdateModel(master) binds all the properties correctly. But when I call dbContext.SaveChanges it issues the follow sql from sql profiler (psuedo code)

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

I've got a work around that works but it's pretty hackish and I'm currently not matching up the keys so it's dependent on everything coming back in the right order. Plus I've got to include all the fields that I want updated.

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

I've got a feeling that UpdateModel is somehow removing and re-adding the children.

Has anyone else got this to work? Of course, I could throw in the towel and parse the indexed field names myself, but I'm so close!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

嘴硬脾气大 2024-10-23 16:40:27

它应该可以工作 - 我在 MVC2 中的类似代码没有遇到任何问题。

但我担心这一行:
[5]“详细信息”

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

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

It should work - I haven't had any problems with similar code in MVC2.

I'm worried about this line though:
[5] "Details"

What's it sending back in details? I expect this could be causing the problem - Not entirely sure how the model binder works in MVC 3, but I'd expect this line would cause it to set the Details collection to NULL.

You shouldn't have to rely on the fields returning in a specific order - the binder would be designed to handle them in any order.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文