我正在尝试单独更新每个产品,其中多个产品可以在一个订单中找到。当我按提交/更新时,我将orderid与新产品数量一起发送到控制器。这是我显示的错误:“System.Data.SqlClient.SqlException:不允许新事务,因为会话中还有其他线程运行。”
这是重定向到表单的控制器。
[HttpGet]
[Authorize(Roles = "ADM")]
public ActionResult UpdateDetails(Guid id)
{
BusinessLayer.Orders blorder = new BusinessLayer.Orders();
return View(blorder.GetOrderDetailsByOrderId(id));
}
这是表格。
@model IQueryable<CommonLayer.ORDERDETAIL>
@{
ViewBag.Title = "UpdateDetails";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>UpdateDetails</h2>
<table class="table table-striped" style="font-size:medium;">
<tr>
<th>
Order Details ID
</th>
<th>
Price
</th>
<th>
VAT Rate
</th>
<th>
Quantity
</th>
</tr>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.OrderDetailsId)
</td>
<td>
@Html.DisplayFor(modelItem => item.ProductPrice)
</td>
<td>
@Html.DisplayFor(modelItem => item.ProductVATRate)
</td>
<td>
<form action="/order/updatedetails/@item.OrderDetailsId" method="post" enctype="multipart/form-data">
<input type="text" name="prodqty" value="@item.ProductQuantity" />
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<br />
<input type="submit" value="Update" class="btn btn-primary" />
</div>
</div>
</form>
</td>
</tr>
}
</table>
这是表单重定向到的控制器。
[HttpPost]
[Authorize(Roles = "ADM")]
public ActionResult UpdateDetails(Guid id, int prodqty)
{
BusinessLayer.Orders blorder = new BusinessLayer.Orders();
CommonLayer.ORDERDETAIL orderdetail = blorder.GetOrderDetailByDetailId(id);
blorder.UpdateOrderDetails(orderdetail, prodqty);
return RedirectToAction("ViewOrder");
}
这是用于实际更新股票的代码。
public void UpdateOrderDetails(CommonLayer.ORDERDETAIL orderdetail, int prodqty)
{
CommonLayer.ORDERDETAIL orderDetails = this.GetOrderDetail(orderdetail.OrderDetailsOrderId);
CommonLayer.ORDERDETAIL od = new CommonLayer.ORDERDETAIL();
DataLayer.DAProducts daprod = new DataLayer.DAProducts(this.Entities);
CommonLayer.PRODUCT product = daprod.GetProduct(orderDetails.OrderDetailsProductId);
od.OrderDetailsProductId = orderDetails.OrderDetailsProductId;
od.OrderDetailsId = orderDetails.OrderDetailsId;
od.OrderDetailsOrderId = orderDetails.OrderDetailsOrderId;
od.ProductVATRate = orderDetails.ProductVATRate;
od.ProductPrice = orderDetails.ProductPrice;
od.ProductQuantity = prodqty;
if (od.ProductQuantity <= product.ProductQuantity)
{
if (od.ProductQuantity > orderDetails.ProductQuantity)
{
product.ProductQuantity -= (od.ProductQuantity - orderDetails.ProductQuantity);
daprod.UpdateProduct(product);
this.Entities.Entry(orderDetails).CurrentValues.SetValues(od);
this.Entities.SaveChanges();
}
else if (od.ProductQuantity < orderDetails.ProductQuantity)
{
product.ProductQuantity += (orderDetails.ProductQuantity - od.ProductQuantity);
daprod.UpdateProduct(product);
this.Entities.Entry(orderDetails).CurrentValues.SetValues(od);
this.Entities.SaveChanges();
}
}
else
{
throw new Exception("Stock is too low");
}
}
这就是错误显示在“this.Entities.SaveChanges();”
上public void UpdateProduct(CommonLayer.PRODUCT product)
{
CommonLayer.PRODUCT ExistingProduct = this.GetProduct(product.ProductId);
this.Entities.Entry(ExistingProduct).CurrentValues.SetValues(product);
this.Entities.SaveChanges();
}
任何帮助都会非常感激,因为我似乎无法找到解决此错误的方法。谢谢!
答案 0 :(得分:0)
一个好的做法是在控制器中放入开始,保存/回滚事务,以避免在核心函数SaveChanges
和{{1}中执行UpdateProduct
次调用的多个实例..} ..触发了线程异常
尝试此操作,删除核心功能UpdateOrderDetails
和SaveChanges
上的所有现有UpdateProduct
来电,并将其置于您的控制器中
UpdateOrderDetails
在这里,您可以看到您可以检测到记录是否已正确保存,在这种情况下您可以将其提交到数据库,否则您只需回滚事务
所有这些片段作为评论可以根据您声明实体的方式而有所不同,但这应该有助于解决您的问题,同时遵循在MVC中使用事务的良好实践
答案 1 :(得分:0)
天上。我认为你太过于重复使用你的实体了。尝试为您使用的每笔交易初始化新的上下文...执行此操作(同样,从SaveChanges
函数中删除UpdateProduct
,这样您只需拨打SaveChanges
一次...试试这个在if-else-if
阻止
using(var context = new CommonLayer.DBModelEntities()){
if (od.ProductQuantity > orderDetails.ProductQuantity)
{
product.ProductQuantity -= (od.ProductQuantity - orderDetails.ProductQuantity);
daprod.UpdateProduct(product, context);
context.Entry(orderDetails).CurrentValues.SetValues(od);
}
else if (od.ProductQuantity < orderDetails.ProductQuantity)
{
product.ProductQuantity += (orderDetails.ProductQuantity - od.ProductQuantity);
daprod.UpdateProduct(product, context);
context.Entry(orderDetails).CurrentValues.SetValues(od);
}
context.SaveChanges();
}
有了这个,您还应该更改UpdateProduct
函数以接收您正在使用的当前数据库上下文
public void UpdateProduct(CommonLayer.PRODUCT product, CommonLayer.DBModelEntities context)
{
CommonLayer.PRODUCT ExistingProduct = this.GetProduct(product.ProductId);
context.Entry(ExistingProduct).CurrentValues.SetValues(product);
}