加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 在修改现有子实体框架的同时添加新的子对象

发布时间:2020-12-16 07:45:14 所属栏目:asp.Net 来源:网络整理
导读:我看一下类似问题的一些答案,但它们似乎并不适合我的. 我正在尝试合并来自实体框架的模式:DbContext(第90页),它似乎不起作用.我正在使用的代码如下: [HttpPost]public ActionResult Edit(Order order){ if (ModelState.IsValid) { db.Orders.Add(order); d
我看一下类似问题的一些答案,但它们似乎并不适合我的.

我正在尝试合并来自实体框架的模式:DbContext(第90页),它似乎不起作用.我正在使用的代码如下:

[HttpPost]
public ActionResult Edit(Order order)
{
     if (ModelState.IsValid)
     {
         db.Orders.Add(order);
         db.Entry(order).State = EntityState.Modified;

         foreach (var orderDetail in order.OrderDetails)
         {
              if (orderDetail.OrderId == 0)
              {
                  db.Entry(orderDetail).State = EntityState.Added;
              }
              else
              {
                  db.Entry(orderDetail).State = EntityState.Modified;
              }
              // The example order that I'm updating has two child entities
              // so this orderId will be for the third,added one.
              int addedOrderDetailId = order.OrderDetails[2].OrderId;
          }
          db.SaveChanges();
          return RedirectToAction("Index");
     }

     ViewBag.CustomerId = new SelectList(db.Customers,"CustomerId","CompanyName",order.CustomerId);

     return View(order);

}

我一直在运行一个示例,其中Order对象有两个现有的OrderDetail对象,我正在尝试添加第三个.我包含了addedOrderDetailId变量,因此我可以将它添加到’Watch’并查看它何时更改

我发现正在发生的是添加的OrderDetail对象的OrderId(当输入foreach循环时为0)正由实体框架更新到Order对象的OrderId.这发生在第一次迭代到foreach循环之后(当第一个子实体的状态更改为修改时.这意味着所有三个子节点都被标记为已修改.这导致SaveChanges()尝试更新条目进入不存在的数据库.

如果有其他人遇到过这个问题,那么我会很乐意为你解决这个问题.我还必须处理被删除的现有子对象,但我还没有解决这个问题,所以如果有人知道这种模式,那也值得赞赏.

编辑:

在获取Slauma的建议并删除db.Orders.Add(order)之后.我能够将调用移动到foreach循环下面的db.Entry(order).State.这允许我遍历循环并将每个OrderDetail对象的状态设置为针对现有对象进行修改并添加为添加的对象.然后,我只需将父级的OrderId分配给子级的OrderId,并且更新成功.我还包括了我在编辑过程中用来删除子对象的代码.我不确定这是多么有效,但它确实有效.这是修改后的代码:

[HttpPost]
    public ActionResult Edit(Order order)
    {
        if (ModelState.IsValid)
        {
            List<int> previousProductIds = db.OrderDetails
                .Where(ep => ep.OrderId == order.OrderId)
                .Select(ep => ep.ProductId)
                .ToList();

            List<int> currentProductIds = order.OrderDetails
                .Select(o => o.ProductId)
                .ToList();

            List<int> deletedProductIds = previousProductIds
                .Except(currentProductIds).ToList();


            foreach (var deletedProductId in deletedProductIds)
            {
                OrderDetail deletedOrderDetail = db.OrderDetails
                    .Where(od => od.OrderId == order.OrderId && od.ProductId == deletedProductId)
                    .Single();

                db.Entry(deletedOrderDetail).State = EntityState.Deleted;
            }

            foreach (var orderDetail in order.OrderDetails)
            {
                if (orderDetail.OrderId == 0)
                {
                    db.Entry(orderDetail).State = EntityState.Added;
                    orderDetail.OrderId = order.OrderId;
                }
                else
                {
                    db.Entry(orderDetail).State = EntityState.Modified;
                }
            }
            db.Entry(order).State = EntityState.Modified;
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        ViewBag.CustomerId = new SelectList(db.Customers,order.CustomerId);
        return View(order);
    }

解决方法

从代码中删除此行:

db.Orders.Add(order);

这实际上会将包括所有orderDetails的订单置于已添加状态.关系修正(在Add中自动发生)会将所有OrderDetails的OrderId设置为订单的键.当你输入循环orderDetail.OrderId是!= 0表示所有细节项目,你总是输入将状态设置为Modified的分支.循环结束时,orderDetail项目不再处于已添加状态.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读