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
相关产品推荐
相关产品推荐

