代码之家  ›  专栏  ›  技术社区  ›  mare

从带有“发布到编辑”操作的ASP.NET MVC页更新实体

  •  1
  • mare  · 技术社区  · 15 年前

    我的表单包括客户机实体属性的子集,还包括一个隐藏字段,其中包含客户机的ID。客户端实体本身通过get 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 回复  |  直到 12 年前
        1
  •  1
  •   John Farrell    15 年前

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

    edmx.Clients.Attach(client);
    edmx.SaveChanges();
    
        2
  •  0
  •   Cephas    15 年前

    我不知道怎么做才好。 看起来这应该是一个附加编辑对象并保存更改的案例,但是框架不能这样工作。

    简而言之,savechanges magic只适用于从您使用的上下文创建的实体对象。控制器创建的实体对象不符合条件。

    尝试类似的方法(MVC 2和EF4)

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

    它确实需要一个查询来进行更新,但我还没有遇到一个健壮的方法来解决它。 D

        3
  •  0
  •   Greg Quinn    12 年前

    您可以像这样使用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();
        }