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

ASP.NET MVC中点击提交按钮同时编辑表记录并新增另一表记录的实现

实现提交评论时同步更新文章与新增评论(Repository模式)

核心思路

  • 用事务保证两个数据库操作的原子性,要么全部成功,要么全部回滚
  • 拆分职责:Repository层专注单表数据操作,业务逻辑层(Service)协调两个Repository的执行

步骤实现

1. 定义Repository接口

遵循单一职责,分别为文章和评论定义独立的Repository接口:

// 文章Repository接口
public interface IArticleRepository
{
    // 根据ID查询文章
    Task<Article> GetByIdAsync(int articleId);
    // 更新文章信息(如评论数、最后评论时间)
    Task UpdateAsync(Article article);
}

// 评论Repository接口
public interface ICommentRepository
{
    // 添加新评论
    Task AddAsync(Comment comment);
}

2. 实现Repository(以EF Core为例)

基于ORM框架实现具体的数据操作逻辑:

public class ArticleRepository : IArticleRepository
{
    private readonly AppDbContext _dbContext;

    public ArticleRepository(AppDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public async Task<Article> GetByIdAsync(int articleId)
    {
        return await _dbContext.Articles.FindAsync(articleId);
    }

    public async Task UpdateAsync(Article article)
    {
        _dbContext.Articles.Update(article);
        await _dbContext.SaveChangesAsync();
    }
}

public class CommentRepository : ICommentRepository
{
    private readonly AppDbContext _dbContext;

    public CommentRepository(AppDbContext dbContext)
    {
        _dbContext = dbContext;
    }

    public async Task AddAsync(Comment comment)
    {
        await _dbContext.Comments.AddAsync(comment);
        await _dbContext.SaveChangesAsync();
    }
}

3. 业务逻辑层协调跨表操作

在Service层开启事务,串联两个Repository的操作,确保数据一致性:

public class CommentService
{
    private readonly IArticleRepository _articleRepo;
    private readonly ICommentRepository _commentRepo;
    private readonly AppDbContext _dbContext;

    public CommentService(IArticleRepository articleRepo, ICommentRepository commentRepo, AppDbContext dbContext)
    {
        _articleRepo = articleRepo;
        _commentRepo = commentRepo;
        _dbContext = dbContext;
    }

    public async Task SubmitCommentAsync(int articleId, string commentContent, string userId)
    {
        using var transaction = await _dbContext.Database.BeginTransactionAsync();
        try
        {
            // 1. 查询目标文章
            var article = await _articleRepo.GetByIdAsync(articleId);
            if (article == null)
            {
                throw new ArgumentException("目标文章不存在");
            }

            // 2. 更新文章的评论统计信息
            article.CommentCount++;
            article.LastCommentTime = DateTime.UtcNow;
            await _articleRepo.UpdateAsync(article);

            // 3. 创建并保存新评论
            var newComment = new Comment
            {
                ArticleId = articleId,
                Content = commentContent,
                UserId = userId,
                CreateTime = DateTime.UtcNow
            };
            await _commentRepo.AddAsync(newComment);

            // 提交事务
            await transaction.CommitAsync();
        }
        catch
        {
            // 操作失败回滚事务
            await transaction.RollbackAsync();
            throw; // 抛出异常交由上层处理
        }
    }
}

4. 表单提交接口(Controller层)

接收前端表单请求,调用Service完成业务操作:

[ApiController]
[Route("api/comments")]
public class CommentController : ControllerBase
{
    private readonly CommentService _commentService;

    public CommentController(CommentService commentService)
    {
        _commentService = commentService;
    }

    [HttpPost]
    public async Task<IActionResult> SubmitComment([FromForm] CommentSubmitModel model)
    {
        try
        {
            // 假设从当前登录用户获取UserId
            await _commentService.SubmitCommentAsync(model.ArticleId, model.Content, User.Identity.Name);
            return Ok("评论提交成功");
        }
        catch (ArgumentException ex)
        {
            return BadRequest(ex.Message);
        }
        catch
        {
            return StatusCode(500, "服务器内部错误");
        }
    }
}

// 表单提交数据模型
public class CommentSubmitModel
{
    public int ArticleId { get; set; }
    public string Content { get; set; }
}

关键注意事项

  • 事务必须开启:杜绝评论新增成功但文章更新失败的不一致情况
  • Repository保持单一职责:不要在Repository层处理跨表业务逻辑
  • 异常处理要完整:捕获异常后及时回滚事务,并向前端反馈错误信息

内容的提问来源于stack exchange,提问作者Meysam vahdat panah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 14:01:36