在 ASP.NET Core 中,使用工作单元模式(Unit of Work)可以有效地管理数据库事务。通过定义一个能够开启、提交和回滚事务的工作单元接口及其实现,结合仓储层和服务层,可以让数据操作更加清晰和可靠。以下是详细说明。
- 定义工作单元接口 IUnitOfWork
该接口将包含开启、提交和回滚事务的方法:
| public interface IUnitOfWork : IDisposable |
| { |
| Task BeginTransactionAsync(); |
| Task CommitAsync(); |
| Task RollbackAsync(); |
| Task<int> SaveChangesAsync(); |
| } |
- 实现工作单元类 UnitOfWork
在实现类中,我们需要使用 DbContext 来控制数据库操作,并管理事务的开启、提交和回滚:
| public class UnitOfWork : IUnitOfWork |
| { |
| private readonly AppDbContext _context; |
| private IDbContextTransaction _transaction; |
| |
| public UnitOfWork(AppDbContext context) |
| { |
| _context = context; |
| } |
| |
| public async Task BeginTransactionAsync() |
| { |
| _transaction = await _context.Database.BeginTransactionAsync(); |
| } |
| |
| public async Task CommitAsync() |
| { |
| await _context.SaveChangesAsync(); |
| await _transaction.CommitAsync(); |
| } |
| |
| public async Task RollbackAsync() |
| { |
| await _transaction.RollbackAsync(); |
| } |
| |
| public async Task<int> SaveChangesAsync() |
| { |
| return await _context.SaveChangesAsync(); |
| } |
| |
| public void Dispose() |
| { |
| _transaction?.Dispose(); |
| _context?.Dispose(); |
| } |
| } |
- 定义仓储接口 IRepository
与之前相同,定义仓储接口以提供 CRUD 操作:
| public interface IRepository<T> where T : class |
| { |
| Task<IEnumerable<T>> GetAllAsync(); |
| Task<T> GetByIdAsync(int id); |
| Task AddAsync(T entity); |
| Task UpdateAsync(T entity); |
| Task DeleteAsync(int id); |
| } |
- 实现仓储类 Repository
实现该接口,使数据访问更为简单:
| public class Repository<T> : IRepository<T> where T : class |
| { |
| private readonly AppDbContext _context; |
| private readonly DbSet<T> _dbSet; |
| |
| public Repository(AppDbContext context) |
| { |
| _context = context; |
| _dbSet = context.Set<T>(); |
| } |
| |
| public async Task<IEnumerable<T>> GetAllAsync() |
| { |
| return await _dbSet.ToListAsync(); |
| } |
| |
| public async Task<T> GetByIdAsync(int id) |
| { |
| return await _dbSet.FindAsync(id); |
| } |
| |
| public async Task AddAsync(T entity) |
| { |
| await _dbSet.AddAsync(entity); |
| } |
| |
| public async Task UpdateAsync(T entity) |
| { |
| _dbSet.Update(entity); |
| } |
| |
| public async Task DeleteAsync(int id) |
| { |
| var entity = await GetByIdAsync(id); |
| if (entity != null) |
| { |
| _dbSet.Remove(entity); |
| } |
| } |
| } |
- 定义服务层接口 IProductService
服务层接口用于业务逻辑的处理:
| public interface IProductService |
| { |
| Task<IEnumerable<Product>> GetAllProductsAsync(); |
| Task<Product> GetProductByIdAsync(int id); |
| Task AddProductAsync(Product product); |
| Task UpdateProductAsync(Product product); |
| Task DeleteProductAsync(int id); |
| } |
- 实现服务层类 ProductService
在服务层中包含事务控制:
| public class ProductService : IProductService |
| { |
| private readonly IRepository<Product> _productRepository; |
| private readonly IUnitOfWork _unitOfWork; |
| |
| public ProductService(IRepository<Product> productRepository, IUnitOfWork unitOfWork) |
| { |
| _productRepository = productRepository; |
| _unitOfWork = unitOfWork; |
| } |
| |
| public async Task<IEnumerable<Product>> GetAllProductsAsync() |
| { |
| return await _productRepository.GetAllAsync(); |
| } |
| |
| public async Task<Product> GetProductByIdAsync(int id) |
| { |
| return await _productRepository.GetByIdAsync(id); |
| } |
| |
| public async Task AddProductAsync(Product product) |
| { |
| await _unitOfWork.BeginTransactionAsync(); |
| try |
| { |
| await _productRepository.AddAsync(product); |
| await _unitOfWork.SaveChangesAsync(); |
| await _unitOfWork.CommitAsync(); |
| } |
| catch |
| { |
| await _unitOfWork.RollbackAsync(); |
| throw; |
| } |
| } |
| |
| public async Task UpdateProductAsync(Product product) |
| { |
| await _unitOfWork.BeginTransactionAsync(); |
| try |
| { |
| await _productRepository.UpdateAsync(product); |
| await _unitOfWork.SaveChangesAsync(); |
| await _unitOfWork.CommitAsync(); |
| } |
| catch |
| { |
| await _unitOfWork.RollbackAsync(); |
| throw; |
| } |
| } |
| |
| public async Task DeleteProductAsync(int id) |
| { |
| await _unitOfWork.BeginTransactionAsync(); |
| try |
| { |
| await _productRepository.DeleteAsync(id); |
| await _unitOfWork.SaveChangesAsync(); |
| await _unitOfWork.CommitAsync(); |
| } |
| catch |
| { |
| await _unitOfWork.RollbackAsync(); |
| throw; |
| } |
| } |
| } |
- 创建控制器 ProductsController
控制器处理 HTTP 请求并调用服务层的方法:
| [ApiController] |
| [Route("api/[controller]")] |
| public class ProductsController : ControllerBase |
| { |
| private readonly IProductService _productService; |
| |
| public ProductsController(IProductService productService) |
| { |
| _productService = productService; |
| } |
| |
| [HttpGet] |
| public async Task<IActionResult> GetAll() |
| { |
| var products = await _productService.GetAllProductsAsync(); |
| return Ok(products); |
| } |
| |
| [HttpGet("{id}")] |
| public async Task<IActionResult> GetById(int id) |
| { |
| var product = await _productService.GetProductByIdAsync(id); |
| return product != null ? Ok(product) : NotFound(); |
| } |
| |
| [HttpPost] |
| public async Task<IActionResult> Create(Product product) |
| { |
| await _productService.AddProductAsync(product); |
| return CreatedAtAction(nameof(GetById), new { id = product.Id }, product); |
| } |
| |
| [HttpPut("{id}")] |
| public async Task<IActionResult> Update(int id, Product product) |
| { |
| if (id != product.Id) |
| { |
| return BadRequest(); |
| } |
| await _productService.UpdateProductAsync(product); |
| return NoContent(); |
| } |
| |
| [HttpDelete("{id}")] |
| public async Task<IActionResult> Delete(int id) |
| { |
| await _productService.DeleteProductAsync(id); |
| return NoContent(); |
| } |
| } |
总结
通过以上步骤,您已经成功实现了一个带有事务控制的工作单元接口及其实现类,同时定义了仓储层和服务层的结构,控制器也进行了相应的适配。这样的设计可以有效地管理和维护数据库事务,提高代码的健壮性与清晰度。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构