You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 18:10:28