






















设计模式落地:Repository + UnitOfWork + CQRS 完整实现
Repository(仓储模式):封装数据访问,业务层不直接操作 DB,解耦数据层
UnitOfWork(工作单元):统一管理事务,保证多仓储操作原子性(要么全成功,要么全回滚)
Project/ ├─ Entities/ # 领域实体(数据库映射对象) ├─ Repositories/ # 仓储 + 工作单元 │ ├─ IRepository.cs │ ├─ Repository.cs │ ├─ IUnitOfWork.cs │ └─ UnitOfWork.cs ├─ CQRS/ # CQRS 命令 + 查询 │ ├─ Commands/ # 增删改(写操作) │ └─ Queries/ # 查询(读操作) ├─ Data/ # 数据库上下文 │ └─ AppDbContext.cs └─ Services/ # 业务调用层 // Entities/Product.cs public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public int Stock { get; set; } } // Data/AppDbContext.cs using Microsoft.EntityFrameworkCore; public class AppDbContext : DbContext { public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } public DbSet<Product> Products => Set<Product>(); } // Repositories/IRepository.cs using System.Linq.Expressions; public interface IRepository<T> where T : class { // 查询 Task<T> GetByIdAsync(int id); Task<List<T>> GetAllAsync(); Task<List<T>> FindAsync(Expression<Func<T, bool>> predicate); // 写入 Task AddAsync(T entity); void Update(T entity); void Delete(T entity); } // Repositories/Repository.cs using Microsoft.EntityFrameworkCore; using System.Linq.Expressions; public class Repository<T> : IRepository<T> where T : class { protected readonly AppDbContext _dbContext; private readonly DbSet<T> _dbSet; public Repository(AppDbContext dbContext) { _dbContext = dbContext; _dbSet = _dbContext.Set<T>(); } public async Task<T> GetByIdAsync(int id) => await _dbSet.FindAsync(id); public async Task<List<T>> GetAllAsync() => await _dbSet.ToListAsync(); public async Task<List<T>> FindAsync(Expression<Func<T, bool>> predicate) => await _dbSet.Where(predicate).ToListAsync(); public async Task AddAsync(T entity) => await _dbSet.AddAsync(entity); public void Update(T entity) => _dbSet.Update(entity); public void Delete(T entity) => _dbSet.Remove(entity); } // Repositories/IUnitOfWork.cs public interface IUnitOfWork : IDisposable { // 暴露具体仓储 IRepository<Product> Products { get; } // 统一提交事务 Task<int> SaveChangesAsync(); } // Repositories/UnitOfWork.cs public class UnitOfWork : IUnitOfWork { private readonly AppDbContext _dbContext; private IRepository<Product> _productRepository; public UnitOfWork(AppDbContext dbContext) { _dbContext = dbContext; } // 懒加载仓储 public IRepository<Product> Products { get => _productRepository ??= new Repository<Product>(_dbContext); } // 提交事务(所有变更一次性保存) public async Task<int> SaveChangesAsync() => await _dbContext.SaveChangesAsync(); // 释放资源 public void Dispose() => _dbContext.Dispose(); } CQRS 核心:查询只读不写,命令只写不改 // CQRS/Queries/GetProductByIdQuery.cs public class GetProductByIdQuery { private readonly IUnitOfWork _uow; public GetProductByIdQuery(IUnitOfWork uow) { _uow = uow; } public async Task<Product> ExecuteAsync(int id) { return await _uow.Products.GetByIdAsync(id); } } // CQRS/Queries/GetAllProductsQuery.cs public class GetAllProductsQuery { private readonly IUnitOfWork _uow; public GetAllProductsQuery(IUnitOfWork uow) { _uow = uow; } public async Task<List<Product>> ExecuteAsync() { return await _uow.Products.GetAllAsync(); } } // CQRS/Commands/CreateProductCommand.cs public class CreateProductCommand { private readonly IUnitOfWork _uow; public CreateProductCommand(IUnitOfWork uow) { _uow = uow; } public async Task ExecuteAsync(Product product) { await _uow.Products.AddAsync(product); await _uow.SaveChangesAsync(); // 提交事务 } } // CQRS/Commands/UpdateProductCommand.cs public class UpdateProductCommand { private readonly IUnitOfWork _uow; public UpdateProductCommand(IUnitOfWork uow) { _uow = uow; } public async Task ExecuteAsync(Product product) { _uow.Products.Update(product); await _uow.SaveChangesAsync(); } } // 注册DbContext builder.Services.AddDbContext<AppDbContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))); // 注册 Uow + Repository builder.Services.AddScoped<IUnitOfWork, UnitOfWork>(); // 注册 CQRS builder.Services.AddScoped<GetAllProductsQuery>(); builder.Services.AddScoped<GetProductByIdQuery>(); builder.Services.AddScoped<CreateProductCommand>(); builder.Services.AddScoped<UpdateProductCommand>(); [ApiController] [Route("api/products")] public class ProductController : ControllerBase { private readonly CreateProductCommand _createCommand; private readonly GetProductByIdQuery _getByIdQuery; private readonly GetAllProductsQuery _getAllQuery; // 构造函数注入 public ProductController( CreateProductCommand createCommand, GetProductByIdQuery getByIdQuery, GetAllProductsQuery getAllQuery) { _createCommand = createCommand; _getByIdQuery = getByIdQuery; _getAllQuery = getAllQuery; } // 查询(CQRS 读) [HttpGet("{id}")] public async Task<IActionResult> Get(int id) { var product = await _getByIdQuery.ExecuteAsync(id); return Ok(product); } // 命令(CQRS 写) [HttpPost] public async Task<IActionResult> Create(Product product) { await _createCommand.ExecuteAsync(product); return Created("", product); } } • 查询:Controller → Query → Repository → DB • 写入:Controller → Command → UnitOfWork → 多 Repository 统一提交事务 • 事务保证:多个仓储操作(如新增订单 + 扣库存)只需一次 SaveChangesAsync()
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。