在C#项目中落地CQRS(命令查询职责分离)并不需要一步到位使用复杂框架,可以根据团队规模与业务复杂度选择不同实现方式。下面介绍六种在C#里实现CQRS模式的常见做法。

一、基础分层拆分方式
最直观的做法是把命令(写)和查询(读)分到不同类与接口中,共享同一个数据库但逻辑隔离。
// 命令侧
public class CreateOrderCommand
{
public string ProductName { get; set; }
public int Count { get; set; }
}
public class OrderCommandHandler
{
public void Handle(CreateOrderCommand cmd)
{
// 执行写入逻辑
}
}
// 查询侧
public class OrderQueryService
{
public OrderDto GetOrder(int id)
{
// 执行读取逻辑
return null;
}
}
二、使用MediatR中介者模式
通过MediatR将命令与查询统一走中介管道,读写处理器完全分开,便于加日志或验证。
using MediatR;
public class GetOrderQuery : IRequest<OrderDto>
{
public int Id { get; set; }
}
public class GetOrderHandler : IRequestHandler<GetOrderQuery, OrderDto>
{
public Task<OrderDto> Handle(GetOrderQuery q, CancellationToken ct)
{
return Task.FromResult(new OrderDto());
}
}
三、读写库物理分离
命令写主库,查询读从库或只读模型,利用不同存储结构优化性能。
public class WriteRepository
{
public void Add(Order o) { /* 写主库 */ }
}
public class ReadRepository
{
public OrderView Get(int id) { /* 读从库 */ return null; }
}
四、事件溯源方式
写操作只追加事件,查询由事件回放或投影生成,适合审计要求高的系统。
public interface IEvent { }
public class OrderCreated : IEvent
{
public string ProductName { get; set; }
}
public class EventStore
{
public void Append(IEvent e) { /* 保存事件 */ }
}
五、聚合根加领域事件
领域层用聚合根处理命令并发出领域事件,查询侧订阅事件更新读模型。
public class Order
{
public void Create()
{
// 状态变更并触发领域事件
}
}
六、轻量委托封装
小项目可用委托直接区分读写函数,不引入额外依赖。
public class OrderService
{
public Action<CreateOrderCommand> Command { get; set; }
public Func<int, OrderDto> Query { get; set; }
}
总结
以上六种C#实现CQRS模式的方式从简单到复杂覆盖多数场景。基础拆分适合起步,MediatR提升扩展性,读写分离与事件溯源应对高性能与审计,团队可按需选用。