C# MVC中为关联表特定Id实现Payment表IndexOrder自增
问题描述
我有一个名为Payment的数据库表,包含IndexOrder列。需求是:新增Payment记录时,AddEdit方法需要先检查特定Id对应的IndexOrder列是否有值,若存在则将IndexOrder自增1,每新增一条对应Id的Payment记录都要遵循这个逻辑。
现有AddEdit方法代码如下:
[HttpPost] public ActionResult AddEdit(PaymentModel model) { if (ModelState.IsValid) { var userId = User.Identity.GetUserId(); Payment obj = context.Payment .Where(p => p.Id == model.Id).FirstOrDefault(); if (obj == null) { obj = new Payment(); if (model.File != null) { Guid nme = Guid.NewGuid(); string filename = nme + Path.GetExtension(model.File.FileName); string filepath = Path.Combine(Server.MapPath("/FilesUpload/") + filename); model.File.SaveAs(filepath); obj.Path = filename; } Mapper.FillObjectFromModel(obj, model); obj.CreatedBy = userId; obj.ModifiedBy = userId; obj.CreatedAt = DateTime.Now; obj.ModifiedAt = DateTime.Now; context.Payment.Add(obj); context.SaveChanges();
解决方案
要实现需求中的IndexOrder自增逻辑,需在新增记录前查询对应Id下的最大IndexOrder值,再计算新值赋值。同时修正代码中的路径拼接问题,并补充完整方法逻辑:
[HttpPost] public ActionResult AddEdit(PaymentModel model) { if (ModelState.IsValid) { var userId = User.Identity.GetUserId(); Payment obj = context.Payment .Where(p => p.Id == model.Id).FirstOrDefault(); if (obj == null) { obj = new Payment(); if (model.File != null) { Guid nme = Guid.NewGuid(); string filename = nme + Path.GetExtension(model.File.FileName); // 修正Path.Combine用法,避免路径拼接错误 string filepath = Path.Combine(Server.MapPath("/FilesUpload/"), filename); model.File.SaveAs(filepath); obj.Path = filename; } // 处理IndexOrder自增逻辑 // 用可空类型接收Max结果,避免无记录时抛出异常 var maxIndexOrder = context.Payment .Where(p => p.Id == model.Id) .Max(p => (int?)p.IndexOrder); // 无对应记录时设为1,可根据业务需求调整初始值 obj.IndexOrder = maxIndexOrder.HasValue ? maxIndexOrder.Value + 1 : 1; Mapper.FillObjectFromModel(obj, model); obj.CreatedBy = userId; obj.ModifiedBy = userId; obj.CreatedAt = DateTime.Now; obj.ModifiedAt = DateTime.Now; context.Payment.Add(obj); context.SaveChanges(); return RedirectToAction("Index"); } else { // 补充现有记录的编辑逻辑 Mapper.FillObjectFromModel(obj, model); obj.ModifiedBy = userId; obj.ModifiedAt = DateTime.Now; context.SaveChanges(); return RedirectToAction("Index"); } } // 模型验证失败时返回视图 return View(model); }
关键说明
- 使用
(int?)p.IndexOrder配合Max方法,可避免无对应Id记录时抛出InvalidOperationException。 - 修正
Path.Combine的调用方式,原代码拼接字符串的写法可能导致路径格式错误。 - 高并发场景下,上述代码可能出现竞态条件,建议补充优化方案:
- 开启数据库事务并添加行级锁,确保查询和插入操作的原子性。
- 给
Payment表添加RowVersion列实现乐观锁,冲突时自动重试操作。
内容的提问来源于stack exchange,提问作者munir
相关产品推荐
相关产品推荐

