工作单元(Unit of Work, UoW)模式是一种用于处理事务性工作的方法,特别适用于需要对数据库进行多次操作时。它的主要目的是将多个数据库操作封装在一个事务中,确保所有操作能整体成功或者整体失败,从而保证数据的一致性。
本文将详细介绍如何在 C# 中实现工作单元模式,并提供完整的代码注释。
下面是实现工作单元模式的步骤:
首先,我们定义一个简单的实体类 Product
。
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AppUnitWork
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
}
接下来,定义各种实体的仓储接口和实现。这里以 Product
为例。
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AppUnitWork
{
public interface IProductRepository
{
IEnumerable<Product> GetAll();
Product GetById(int id);
void Add(Product product);
void Update(Product product);
void Delete(int id);
}
}
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AppUnitWork
{
public class ProductRepository : IProductRepository
{
private readonly AppDbContext _context;
public ProductRepository(AppDbContext context)
{
_context = context;
}
public IEnumerable<Product> GetAll() => _context.Products.ToList();
public Product GetById(int id) => _context.Products.Find(id);
public void Add(Product product)
{
_context.Products.Add(product);
}
public void Update(Product product)
{
_context.Products.Update(product);
}
public void Delete(int id)
{
var product = _context.Products.Find(id);
if (product != null)
{
_context.Products.Remove(product);
}
}
}
}
定义工作单元以管理多个仓储和事务。
C#public interface IUnitOfWork : IDisposable
{
IProductRepository Products { get; }
int Complete();
}
public class UnitOfWork : IUnitOfWork
{
private readonly AppDbContext _context;
public IProductRepository Products { get; private set; }
public UnitOfWork(AppDbContext context, IProductRepository productRepository)
{
_context = context;
Products = productRepository;
}
public int Complete()
{
return _context.SaveChanges();
}
public void Dispose()
{
_context.Dispose();
}
}
示例调用代码展示了如何使用工作单元和仓储来实现多个数据库操作的事务管理。
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AppUnitWork
{
public class ProductService
{
private readonly IUnitOfWork _unitOfWork;
public ProductService(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
public void PerformProductOperations()
{
// 增加新产品
var newProduct = new Product { Name = "New Product", Price = 99.99m };
_unitOfWork.Products.Add(newProduct);
_unitOfWork.Complete();
Console.WriteLine("Added new product");
// 更新现有产品
var product = _unitOfWork.Products.GetById(1);
if (product != null)
{
product.Price = 79.99m;
_unitOfWork.Products.Update(product);
_unitOfWork.Complete();
Console.WriteLine("Updated existing product");
}
// 删除产品
_unitOfWork.Products.Delete(2);
_unitOfWork.Complete();
Console.WriteLine("Deleted product");
}
}
}
AppDbContext
类确保你已经添加了 Microsoft.EntityFrameworkCore
和 Microsoft.EntityFrameworkCore.InMemory
包。这可以通过 NuGet 包管理器或者在命令行中执行以下命令来完成:
Markdowndotnet add package Microsoft.EntityFrameworkCore dotnet add package Microsoft.EntityFrameworkCore.InMemory
C#using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AppUnitWork
{
public class AppDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// 配置使用内存数据库
optionsBuilder.UseInMemoryDatabase("InMemoryDb");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// 通过种子数据来预填充内存数据库
modelBuilder.Entity<Product>().HasData(
new Product { Id = 1, Name = "Product 1", Price = 10.00m },
new Product { Id = 2, Name = "Product 2", Price = 20.00m }
);
}
}
}
C#using Microsoft.Extensions.DependencyInjection;
using System;
namespace AppUnitWork
{
internal class Program
{
static void Main(string[] args)
{
// 设置依赖注入
var serviceProvider = new ServiceCollection()
.AddDbContext<AppDbContext>()
.AddScoped<IProductRepository, ProductRepository>()
.AddScoped<IUnitOfWork, UnitOfWork>()
.AddScoped<ProductService>()
.BuildServiceProvider();
using (var scope = serviceProvider.CreateScope())
{
var productService = scope.ServiceProvider.GetRequiredService<ProductService>();
productService.PerformProductOperations();
DisplayAllProducts(scope.ServiceProvider.GetRequiredService<IUnitOfWork>());
}
}
static void DisplayAllProducts(IUnitOfWork unitOfWork)
{
var products = unitOfWork.Products.GetAll();
foreach (var product in products)
{
Console.WriteLine($"Product Id: {product.Id}, Name: {product.Name}, Price: {product.Price}");
}
}
}
}
通过应用工作单元模式,我们能够确保多个数据库操作的事务性,这在进行复杂的业务逻辑和数据操作时尤为重要。本文介绍了工作单元模式的基本概念和实现步骤,附带具体的代码示例,希望对你有所帮助。
如果你有任何问题或需要进一步的帮助,请随时与我联系!
本文作者:rick
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!