【问题标题】:DbUpdateConcurrencyException when editing data that already exists even though I pass the variables needed即使我传递了所需的变量,编辑已经存在的数据时也会出现 DbUpdateConcurrencyException
【发布时间】:2015-09-06 06:43:01
【问题描述】:

即使我将OrderID 传递给OrderItem 表单,我也会收到DbUpdateConcurrencyException 错误。它适用于CreateDelete,但它不断将我踢出Edit。任何人都可以建议修复或让我知道我做错了什么吗?

我知道Concurrency Exception Error

System.Data.Entity.Infrastructure.DbUpdateConcurrencyException 是 用户代码未处理 HResult=-2146233087 消息=存储更新, 插入或删除语句影响了意外数量的行 (0)。 自加载实体后,实体可能已被修改或删除。 请参阅http://go.microsoft.com/fwlink/?LinkId=472540 了解有关信息 理解和处理乐观并发异常。
来源=EntityFramework StackTrace: 在 System.Data.Entity.Internal.InternalContext.SaveChanges() 在 System.Data.Entity.Internal.LazyInternalContext.SaveChanges() 在 System.Data.Entity.DbContext.SaveChanges() 在 c:\Users\Luffy\Desktop\HealthHabitat 中的 HealthHabitat.Controllers.OrderItemController.Edit(OrderItem orderItem) V25\HealthHabitat\Controllers\OrderItemController.cs:第 97 行 在 lambda_method(闭包,ControllerBase,对象 []) 在 System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase 控制器,Object[] 参数) 在 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext 控制器上下文,IDictionary2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 参数) 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.ActionInvocation.InvokeSynchronousActionMethod() 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) 在 System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult2.CallEndDelegate(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResultBase1.End() 在 System.Web.Mvc.Async.AsyncResultWrapper.End[TResult](IAsyncResult asyncResult,对象标签) 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult 异步结果) 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.b__3d() 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.AsyncInvocationWithFilters.c__DisplayClass46.b__3f() 内部异常:System.Data.Entity.Core.OptimisticConcurrencyException H结果=-2146233087 Message=Store 更新、插入或删除语句影响了意外数量的行 (0)。实体可能已被修改或 自加载实体后删除。看 http://go.microsoft.com/fwlink/?LinkId=472540 获取有关信息 理解和处理乐观并发异常。 来源=实体框架 堆栈跟踪: 在 System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.ValidateRowsAffected(Int64 rowsAffected,UpdateCommand 源) 在 System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update() 在 System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.b__2(UpdateTranslator ) 在 System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult, Func2 updateFunction) at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update() at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStore>b__35() at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) 在 System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions 选项,IDbExecutionStrategy executionStrategy,布尔值 开始本地事务) 在 System.Data.Entity.Core.Objects.ObjectContext.c__DisplayClass2a.b__27() 在 System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 手术) 在 System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions 选项,布尔型 executeInExistingTransaction) 在 System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions 选项) 在 System.Data.Entity.Internal.InternalContext.SaveChanges() 内部异常:

控制器:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "OrderItemID,OrderID,ItemID,Quantity")] OrderItem orderItem)
{
    if (ModelState.IsValid)
    {
        db.Entry(orderItem).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Details", "Order", new { id = orderItem.OrderID });
    }
    ViewBag.ItemID = new SelectList(db.Items, "ItemID", "Name", orderItem.ItemID);
    ViewBag.OrderID = new SelectList(db.Orders, "OrderID", "OrderID", orderItem.OrderID);
    return View(orderItem);
}

编辑视图:

@using (Html.BeginForm(new { OrderID = Model.OrderID }))
{
    @Html.AntiForgeryToken()
    <div class="panel panel-warning">
        <div class="panel-heading">
        <h4><i class="fa fa-edit"></i> Edit</h4>
        </div>
        <div class="panel-body">
            <div class="form-horizontal">
                <hr />
                @Html.ValidationSummary(true, "", new { @class = "text-danger" })
               @Html.HiddenFor(model => model.OrderID)

                <div class="form-group">
                    @Html.LabelFor(model => model.ItemID, "Item Name", htmlAttributes: new { @class = "control-label col-md-2" })
                    <div class="col-md-10">
                        @Html.DropDownList("ItemID", null, htmlAttributes: new { @class = "form-control"})
                        @Html.ValidationMessageFor(model => model.ItemID, "", new { @class = "text-danger" })
                    </div>
                </div>
                <div class="form-group">
                    @Html.LabelFor(model => model.Quantity, htmlAttributes: new { @class = "control-label col-md-2" })
                    <div class="col-md-10">
                        @Html.EditorFor(model => model.Quantity, new { htmlAttributes = new { @class = "form-control" } })
                        @Html.ValidationMessageFor(model => model.Quantity, "", new { @class = "text-danger" })
                    </div>
                </div>
                <hr />
                    <div class="form-group">
                        <div class="col-md-offset-2 col-md-10">
                            <a href="@Url.Action("Details", "Order", new { id = Model.OrderID }, null)" class="btn btn-default">Cancel</a>
                            <input type="submit" value="Save" class="btn btn-warning"/>
                        </div>
                    </div>
                </div>
            </div>
        </div>
            }

型号:

public class OrderItem
{

    public int OrderItemID { get; set; }
    public int OrderID { get; set; }
    public int ItemID { get; set; }

   [Range(1, 30, ErrorMessage = "{0} must be between {1} and {2}.")] // is this a row version?? I'm not sure, I'm kinda new to MVC
    public int Quantity { get; set; }

    public virtual Order Order { get; set; }
    public virtual Item Item { get; set; }

}

GET 编辑方法

// GET: OrderItem/Edit/5
public ActionResult Edit(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    OrderItem orderItem = db.OrderItems.Find(id);
    if (orderItem == null)
    {
        return HttpNotFound();
    }

    ViewBag.ItemID = new SelectList(db.Items, "ItemID", "Name", orderItem.ItemID);
    ViewBag.OrderID = new SelectList(db.Orders, "OrderID", "OrderID", orderItem.OrderID);
    return View(orderItem);
}

【问题讨论】:

  • OrderItem 有 rowversion 属性吗?

标签: asp.net-mvc exception concurrency


【解决方案1】:

您必须将 RowVersion 属性放在视图上,并将其发送到控制器:

@Html.ValidationSummary(true, "", new { @class = "text-danger" })
@Html.HiddenFor(model => model.OrderID)
@Html.HiddenFor(model => model.RowVersion)

控制器

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "OrderItemID,OrderID,ItemID,Quantity,RowVersion")] OrderItem orderItem)
{
    if (ModelState.IsValid)
    {
        db.Entry(orderItem).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Details", "Order", new { id = orderItem.OrderID });
    }
    ViewBag.ItemID = new SelectList(db.Items, "ItemID", "Name", orderItem.ItemID);
    ViewBag.OrderID = new SelectList(db.Orders, "OrderID", "OrderID", orderItem.OrderID);
    return View(orderItem);
}

请注意,未在视图中修改的属性将为空。最好指定修改后的属性。

//db.Entry(orderItem).State = EntityState.Modified;
db.Entry(orderItem).Property(i => i.Quantity).IsModified = true;
//...

编辑

仅用于测试目的,而不是

@using (Html.BeginForm(new { OrderID = Model.OrderID }))

试试

@using (Html.BeginForm())
{
   @Html.HiddenFor(i => i.OrderID)
}

编辑 2

将您的 GET 操作更改为:

// GET: OrderItem/Edit/5
public ActionResult Edit(int? id)
{
    if (id == null)
    {
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    OrderItem orderItem = db.OrderItems.Find(id);
    if (orderItem == null)
    {
        return HttpNotFound();
    }

    ViewBag.DDL_ItemID = db.Items.Select(i => new SelectListItem { Text = i.Name, Value = i.ItemID.ToString() }).ToList();
    ViewBag.DDL_OrderID = db.Orders.Select(i => new SelectListItem { Text = i.OrderID.ToString(), Value = i.OrderID.ToString() }).ToList();
    return View(orderItem);
}

永远不要使用与 Model 属性同名的 ViewBag 属性

更改视图中的 DropDownList:

@Html.DropDownListFor(i => i.ItemID, (IEnumerable<SelectListItem>)ViewBag.DDL_ItemID, new { @class = "form-control"})

在视图中,您将 OrderItemID 放在哪里?你必须把它放在那里。

【讨论】:

  • 我很抱歉 Fabio,我的桌子没有排版。我误读了我的 OrderItem 表。我还需要改变这条线吗? db.Entry(orderItem).Property(i =&gt; i.Quantity).IsModified = true;
  • 没必要,这只是一个建议,因为您似乎只是在更改此属性...请显示 OrdemItem 类的结构
  • 我已更新问题以包含课程。请参见上文。
  • 您确定所有属性(OrderItemID、OrderID、ItemID 和 Quantity)都在操作帖子中设置了吗?
  • 实际上只有Quantity需要设置,OrderIemIDOrderIDItemID需要保持不变。我也尝试添加db.Entry(orderItem).Property(i =&gt; i.Quantity).IsModified = true;,但isModified 有问题。
猜你喜欢
  • 2020-10-31
  • 2018-10-04
  • 2018-01-27
  • 1970-01-01
  • 1970-01-01
  • 2017-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多