ASP.NET Core中HTML表格多行数据插入数据库的循环错误求助
问题修复方案
核心问题分析
- 前后端属性名不匹配:前端JS中
OrderDetailVM的数量字段是Qty,但后端OrderVm的OrderDetails集合对应属性是Quantity,导致后端无法正确接收数量值,插入时可能为0或null。 - OrderDetail缺少ReservationId传入:前端构建
OrderDetailVM时未添加ReservationId,但后端尝试给OrderDetail赋值该字段,若数据库中该字段为必填项,会直接触发插入错误。 - 循环内频繁调用SaveChanges:foreach循环中每次添加
OrderDetail后都调用SaveChanges(),既降低性能,又可能出现部分数据插入成功、后续出错的不一致情况。 - OrderDate字段类型错误:后端将
DateTime.Now.ToString()赋值给OrderDate,若数据库该字段为DateTime类型,字符串存储会导致类型不匹配。 - OrderNumber格式化错误:原格式
"{0:hhddmmssmmmyyyy}"重复使用mm,导致分钟值被输出两次,格式逻辑错误。 - 未遵循异步规范:同步调用
SaveChanges不符合ASP.NET Core Web API的异步最佳实践,易造成线程阻塞。
修改后的后端代码
public async Task CreateUpdate(OrderVm orderVm) { using var transaction = await _context.Database.BeginTransactionAsync(); try { Order oOrder = new Order(); oOrder.FinalTotal = orderVm.FinalTotal; oOrder.OrderDate = DateTime.Now; // 直接使用DateTime类型,无需转字符串 oOrder.OrderDateTime = DateTime.Now; // 修正OrderNumber格式化逻辑,避免重复输出分钟 oOrder.OrderNumber = String.Format("{0:HHddMMMssyyyy}", DateTime.Now); oOrder.Description = "Hello there"; // 补充Order的ReservationId赋值(如果业务需要) oOrder.ReservationId = orderVm.ReservationId; _context.Orders.Add(oOrder); await _context.SaveChangesAsync(); int orderId = oOrder.OrderId; foreach (var item in orderVm.OrderDetails) { OrderDetail objOrderDetail = new OrderDetail(); objOrderDetail.OrderId = orderId; objOrderDetail.ItemId = item.ItemId; objOrderDetail.ReservationId = item.ReservationId; objOrderDetail.SubTotal = item.SubTotal; objOrderDetail.UnitPrice = item.UnitPrice; objOrderDetail.Quantity = item.Quantity; _context.OrderDetails.Add(objOrderDetail); } // 所有明细添加完成后统一保存,保证原子性并提升性能 await _context.SaveChangesAsync(); await transaction.CommitAsync(); } catch (Exception) { await transaction.RollbackAsync(); throw; // 抛出异常供前端捕获处理 } }
修改后的前端代码
1. 修正AddToChartTable的HTML字符串错误(多余的</tr>)
const AddToChartTable = () => { var tblItemList = $("#tblItemsList"); var unitPrice = $("#txtUnitPrice").val(); var qty = $("#txtQuantity").val(); var itemId = $("#txtItemId").val(); var itemName = $("#txtItemName option:selected").text(); var subtotal = (unitPrice * qty); var itemList = "<tr><td hidden>" + itemId + "</td><td>" + itemName + "</td><td>" + parseFloat(unitPrice).toFixed(2) + "</td><td>" + parseFloat(qty).toFixed(2) + "</td><td>" + parseFloat(subtotal).toFixed(2) + "</td><td> <input type='button' value='Remove' name='Cancel' class='btn btn-danger' onclick='CancelItem(this)' /> </td></tr> "; tblItemList.append(itemList); //FinalItemTotal(); ResetItem(); }
2. 修正FinalPayment的属性匹配与字段缺失问题
const FinalPayment = () => { var objOrderVM = {}; var OrderDetails = new Array(); objOrderVM.ReservationId = $("#txtOrderDetailId").val(); objOrderVM.FinalTotal = $("#txtFinalTotal").val(); $("#tblItemsList").find("tr:gt(0)").each(function () { var OrderDetailVM = {}; OrderDetailVM.SubTotal = parseFloat($(this).find("td:eq(4)").text()); OrderDetailVM.ItemId = parseFloat($(this).find("td:eq(0)").text()); OrderDetailVM.UnitPrice = parseFloat($(this).find("td:eq(2)").text()); // 将Qty改为Quantity,与后端属性名统一 OrderDetailVM.Quantity = parseFloat($(this).find("td:eq(3)").text()); // 补充ReservationId字段,确保后端能接收到 OrderDetailVM.ReservationId = $("#txtOrderDetailId").val(); OrderDetails.push(OrderDetailVM); }); objOrderVM.OrderDetails = OrderDetails; $.ajax({ async: true, type: 'POST', dataType: 'JSON', contentType: 'application/json; charset=utf-8', // 修正分隔符为分号 data: JSON.stringify(objOrderVM), url: '/OrderDetails/AddUpdateOrderDetail', success: function (data) { console.log(data); alert("订单提交成功"); }, error: function (xhr, status, error) { console.error(error); alert("提交失败:" + xhr.responseText); } }); }
内容的提问来源于stack exchange,提问作者Jay Apoulah
相关产品推荐
相关产品推荐

