目录简介什么是Unit of Work模式解决方案使用Unit of Work模式步骤1为Unit of Work创建接口步骤2实现Unit of Work类步骤3在服务层使用Unit of Work内部工作原理使用EF Core上下文的示例使用Unit of Work模式的优势真实示例电子商务订单处理简介当您构建一个连接数据库的应用程序如ASP.NET Core Web API时经常需要一起执行多个数据库操作。例如当用户下订单时您可能需要• 创建新的订单记录• 更新产品库存• 保存支付记录所有这些操作应该一起发生。如果其中一个失败其他操作也不应该被保存。这正是Unit of Work工作单元模式变得非常有用的地方。什么是Unit of Work模式Unit of Work模式是一种设计模式用于在操作数据库时帮助管理事务。它跟踪在业务过程中所做的所有更改然后在单个操作中将它们提交到数据库。如果任何操作失败它可以回滚所有内容——这样您的数据就能保持干净和一致。您可以把它想象成购物车。您可以从购物车中添加或移除商品您的操作但实际的保存只在您结账时提交发生。如果在结账过程中出现问题什么都不会被购买购物车保持原样。没有Unit of Work时的问题让我们先看看不使用此模式时会发生什么。public class ProductService { private readonly ProductRepository _productRepository; private readonly OrderRepository _orderRepository; public ProductService(ProductRepository productRepository, OrderRepository orderRepository) { _productRepository productRepository; _orderRepository orderRepository; } public void CreateOrder(Order order, Product product) { _orderRepository.Add(order); _productRepository.Update(product); // 每个存储库单独保存 _orderRepository.Save(); _productRepository.Save(); } }乍一看这看起来没问题。但存在一个大问题。每个存储库都在单独保存更改。如果订单保存成功但由于数据库错误导致产品更新失败会发生什么您的数据库现在有半完成的数据——订单存在但产品库存没有减少。在真实系统中这很容易导致严重的数据问题。解决方案使用Unit of Work模式Unit of Work模式通过允许您将多个数据库操作分组到单个事务中来修复此问题。这意味着如果某一部分失败所有内容都会自动回滚。让我们看看如何在.NET中逐步构建它。步骤1为Unit of Work创建接口我们首先定义一个简单的接口列出我们的存储库和一个Complete()方法来保存所有更改。public interface IUnitOfWork : IDisposable { IProductRepository Products { get; } IOrderRepository Orders { get; } int Complete(); }这里• Products和Orders是存储库属性。• Complete()将所有更改提交到数据库。• Dispose()确保资源被正确清理。步骤2实现Unit of Work类现在我们实现这个接口。这个类将持有一个共享给所有存储库的DbContext。public class UnitOfWork : IUnitOfWork { private readonly AppDbContext _context; public IProductRepository Products { get; privateset; } public IOrderRepository Orders { get; privateset; } public UnitOfWork(AppDbContext context) { _context context; Products new ProductRepository(_context); Orders new OrderRepository(_context); } public int Complete() { // 一次性保存所有更改 return _context.SaveChanges(); } public void Dispose() { _context.Dispose(); } }现在所有存储库共享一个DbContext。这意味着每个操作都在同一个事务内发生。当您调用Complete()时所有更改一起保存。步骤3在服务层使用Unit of Work让我们在服务类中使用它。public class OrderService { private readonly IUnitOfWork _unitOfWork; public OrderService(IUnitOfWork unitOfWork) { _unitOfWork unitOfWork; } public void CreateOrder(Order order, Product product) { _unitOfWork.Orders.Add(order); _unitOfWork.Products.Update(product); _unitOfWork.Complete(); // 一起保存所有更改 } }现在您可以看到区别。两个存储库都执行操作但只通过Unit of Work调用一次SaveChanges()。如果保存失败数据库中不会存储任何数据从而确保一致性。内部工作原理Unit of Work管理数据库上下文的单个实例。当您执行Add()、Update()或Delete()等操作时这些更改由Entity Framework在内存中跟踪。当您调用Complete()时Unit of Work告诉EF Core在一个事务内提交所有更改。如果在SaveChanges()期间发生错误EF Core会自动回滚事务——意味着不会保存部分数据。使用EF Core上下文的示例如果您使用Entity Framework Core您的DbContext已经像一个小型的Unit of Work。但是当您有多个存储库时使用自定义的Unit of Work可以增加结构并保持代码清洁。这是一个示例AppDbContextpublic class AppDbContext : DbContext { public DbSetProduct Products { get; set; } public DbSetOrder Orders { get; set; } }通过将此AppDbContext注入到UnitOfWork中所有存储库共享相同的上下文。这使得多个更改可以作为一个事务提交。使用Unit of Work模式的优势在.NET项目中使用此模式有几个强有力的理由。1. 数据一致性所有数据库更改作为一个单元处理。如果一个操作失败所有内容都会回滚。这保证了您的数据始终一致。2. 更清晰的代码您只需从Unit of Work调用一次SaveChanges()而不是在每个存储库中调用。这使您的存储库专注于数据访问服务专注于业务逻辑。3. 更易维护当项目增长时您可以轻松地在Unit of Work中添加更多存储库。您不必修改其余代码——只需更新Unit of Work实现。4. 更易测试在单元测试期间您可以模拟Unit of Work和存储库。这有助于您测试业务逻辑而无需实际接触数据库。5. 跨多个存储库的单一事务这是主要好处。当您保存相互依赖的多个实体时您希望要么全部保存要么全部不保存——Unit of Work确保了这一点。真实示例电子商务订单处理让我们看一个简单的真实案例。您正在构建一个电子商务系统客户在其中下订单。当下订单时会发生三件事• 创建订单记录• 更新产品数量• 保存支付日志没有Unit of Work您需要分别保存每一项。但使用Unit of Work_unitOfWork.Orders.Add(order); _unitOfWork.Products.Update(product); _unitOfWork.Payments.Add(payment); _unitOfWork.Complete();所有三个操作将一起保存。如果其中一个失败——例如支付保存失败——所有其他更改将被回滚。这确保您的系统永远不会出现不完整的数据。Unit of Work模式是处理数据库的.NET应用程序中最重要的模式之一。它帮助将多个数据库操作作为单个事务进行管理。当与Repository模式一起使用时效果最佳在业务逻辑和数据访问代码之间提供了清晰的分离。引入地址
数据一致性保障:Unit of Work模式在.NET中的实战指南
发布时间:2026/6/28 2:31:34
目录简介什么是Unit of Work模式解决方案使用Unit of Work模式步骤1为Unit of Work创建接口步骤2实现Unit of Work类步骤3在服务层使用Unit of Work内部工作原理使用EF Core上下文的示例使用Unit of Work模式的优势真实示例电子商务订单处理简介当您构建一个连接数据库的应用程序如ASP.NET Core Web API时经常需要一起执行多个数据库操作。例如当用户下订单时您可能需要• 创建新的订单记录• 更新产品库存• 保存支付记录所有这些操作应该一起发生。如果其中一个失败其他操作也不应该被保存。这正是Unit of Work工作单元模式变得非常有用的地方。什么是Unit of Work模式Unit of Work模式是一种设计模式用于在操作数据库时帮助管理事务。它跟踪在业务过程中所做的所有更改然后在单个操作中将它们提交到数据库。如果任何操作失败它可以回滚所有内容——这样您的数据就能保持干净和一致。您可以把它想象成购物车。您可以从购物车中添加或移除商品您的操作但实际的保存只在您结账时提交发生。如果在结账过程中出现问题什么都不会被购买购物车保持原样。没有Unit of Work时的问题让我们先看看不使用此模式时会发生什么。public class ProductService { private readonly ProductRepository _productRepository; private readonly OrderRepository _orderRepository; public ProductService(ProductRepository productRepository, OrderRepository orderRepository) { _productRepository productRepository; _orderRepository orderRepository; } public void CreateOrder(Order order, Product product) { _orderRepository.Add(order); _productRepository.Update(product); // 每个存储库单独保存 _orderRepository.Save(); _productRepository.Save(); } }乍一看这看起来没问题。但存在一个大问题。每个存储库都在单独保存更改。如果订单保存成功但由于数据库错误导致产品更新失败会发生什么您的数据库现在有半完成的数据——订单存在但产品库存没有减少。在真实系统中这很容易导致严重的数据问题。解决方案使用Unit of Work模式Unit of Work模式通过允许您将多个数据库操作分组到单个事务中来修复此问题。这意味着如果某一部分失败所有内容都会自动回滚。让我们看看如何在.NET中逐步构建它。步骤1为Unit of Work创建接口我们首先定义一个简单的接口列出我们的存储库和一个Complete()方法来保存所有更改。public interface IUnitOfWork : IDisposable { IProductRepository Products { get; } IOrderRepository Orders { get; } int Complete(); }这里• Products和Orders是存储库属性。• Complete()将所有更改提交到数据库。• Dispose()确保资源被正确清理。步骤2实现Unit of Work类现在我们实现这个接口。这个类将持有一个共享给所有存储库的DbContext。public class UnitOfWork : IUnitOfWork { private readonly AppDbContext _context; public IProductRepository Products { get; privateset; } public IOrderRepository Orders { get; privateset; } public UnitOfWork(AppDbContext context) { _context context; Products new ProductRepository(_context); Orders new OrderRepository(_context); } public int Complete() { // 一次性保存所有更改 return _context.SaveChanges(); } public void Dispose() { _context.Dispose(); } }现在所有存储库共享一个DbContext。这意味着每个操作都在同一个事务内发生。当您调用Complete()时所有更改一起保存。步骤3在服务层使用Unit of Work让我们在服务类中使用它。public class OrderService { private readonly IUnitOfWork _unitOfWork; public OrderService(IUnitOfWork unitOfWork) { _unitOfWork unitOfWork; } public void CreateOrder(Order order, Product product) { _unitOfWork.Orders.Add(order); _unitOfWork.Products.Update(product); _unitOfWork.Complete(); // 一起保存所有更改 } }现在您可以看到区别。两个存储库都执行操作但只通过Unit of Work调用一次SaveChanges()。如果保存失败数据库中不会存储任何数据从而确保一致性。内部工作原理Unit of Work管理数据库上下文的单个实例。当您执行Add()、Update()或Delete()等操作时这些更改由Entity Framework在内存中跟踪。当您调用Complete()时Unit of Work告诉EF Core在一个事务内提交所有更改。如果在SaveChanges()期间发生错误EF Core会自动回滚事务——意味着不会保存部分数据。使用EF Core上下文的示例如果您使用Entity Framework Core您的DbContext已经像一个小型的Unit of Work。但是当您有多个存储库时使用自定义的Unit of Work可以增加结构并保持代码清洁。这是一个示例AppDbContextpublic class AppDbContext : DbContext { public DbSetProduct Products { get; set; } public DbSetOrder Orders { get; set; } }通过将此AppDbContext注入到UnitOfWork中所有存储库共享相同的上下文。这使得多个更改可以作为一个事务提交。使用Unit of Work模式的优势在.NET项目中使用此模式有几个强有力的理由。1. 数据一致性所有数据库更改作为一个单元处理。如果一个操作失败所有内容都会回滚。这保证了您的数据始终一致。2. 更清晰的代码您只需从Unit of Work调用一次SaveChanges()而不是在每个存储库中调用。这使您的存储库专注于数据访问服务专注于业务逻辑。3. 更易维护当项目增长时您可以轻松地在Unit of Work中添加更多存储库。您不必修改其余代码——只需更新Unit of Work实现。4. 更易测试在单元测试期间您可以模拟Unit of Work和存储库。这有助于您测试业务逻辑而无需实际接触数据库。5. 跨多个存储库的单一事务这是主要好处。当您保存相互依赖的多个实体时您希望要么全部保存要么全部不保存——Unit of Work确保了这一点。真实示例电子商务订单处理让我们看一个简单的真实案例。您正在构建一个电子商务系统客户在其中下订单。当下订单时会发生三件事• 创建订单记录• 更新产品数量• 保存支付日志没有Unit of Work您需要分别保存每一项。但使用Unit of Work_unitOfWork.Orders.Add(order); _unitOfWork.Products.Update(product); _unitOfWork.Payments.Add(payment); _unitOfWork.Complete();所有三个操作将一起保存。如果其中一个失败——例如支付保存失败——所有其他更改将被回滚。这确保您的系统永远不会出现不完整的数据。Unit of Work模式是处理数据库的.NET应用程序中最重要的模式之一。它帮助将多个数据库操作作为单个事务进行管理。当与Repository模式一起使用时效果最佳在业务逻辑和数据访问代码之间提供了清晰的分离。引入地址