从ASP.NET MVC页面进行实体更新,其中包含post到Edit操作

时间:2010-03-14 22:23:30

标签: asp.net-mvc entity-framework

我的表单包含客户端实体属性的子集,我还包含一个隐藏字段,其中包含客户端的ID。客户端实体本身是通过GET Edit操作提供的。

现在我想进行实体更新,但到目前为止我只是在没有先从数据库加载实体的情况下尝试过。因为POST Edit中的客户端对象具有所需的一切。我想只更新数据存储区中实体的那些属性。

我已将我的应用从3.5移植到4.0 RC1,我的代码现在看起来像这样:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Edit(Client client)
    {
        try
        {
            using (DocInvoiceEntities edmx = new DocInvoiceEntities())
            {
                if (string.IsNullOrEmpty(client.client_firstname))
                    ViewData.ModelState.AddModelError("client_firstname", "Firstname!");

                if (string.IsNullOrEmpty(client.client_lastname))
                    ViewData.ModelState.AddModelError("client_lastname", "Lastname!");

                // postcode
                client.PostCode = (from p in edmx.PostCodes where p.postcode.Equals(client.PostCode.postcode) select p).First();

                // check for errors
                if (!ViewData.ModelState.IsValid)
                    throw new InvalidOperationException();

                // save changes to datastore
                edmx.Clients.Attach(edmx.Clients.Single(c => c.client_id == client.client_id));
                edmx.Clients.ApplyCurrentValues(client);
                edmx.SaveChanges();

            }
            return RedirectToAction("Create", "Invoice");
        }
        catch
        {
            return View();
        }

ApplyCurrentValues()调用抛出此异常: “ObjectContext中的现有对象处于已添加状态。只有在现有对象处于未更改或已修改状态时才能应用更改。”

3 个答案:

答案 0 :(得分:1)

如果您通过您的EntityKey Ids发送,只是想保存您发布的值,那么您只需要:

edmx.Clients.Attach(client);
edmx.SaveChanges();

答案 1 :(得分:0)

我不知道这样做的好方法。 看起来它应该是附加编辑对象并保存更改的情况,但框架不能以这种方式工作。

简而言之,SaveChanges魔术仅适用于从您正在使用的上下文创建的实体对象。控制器创建的实体对象不符合条件。

尝试这样的事情(MVC 2和EF 4)

[HttpPost]
public ActionResult Edit(Client clientToEdit)
{
    db.Client.Attach(db.Client.Single(c => c.ID == clientToEdit.ID));
    db.Client.ApplyCurrentValues(clientToEdit);
    db.SaveChanges();
}

它需要一个查询才能更新,但我没有遇到过一个强有力的方法。 d

答案 2 :(得分:0)

您可以像这样使用TryUpdateModel()......

 [HttpPost]
    public ActionResult Edit(int id, FormCollection collection)
    {
        using (var context = new DocInvoiceEntities())
        {
            var client = context.Clients.Single(u => u.ID == id);

            if (TryUpdateModel(client))
            {
                context.SaveChanges();
                return RedirectToAction("Index");
            }
        }

        return View();
    }