UnitOfWork(工作单元)模式:这是一种设计模式,用于确保对数据库的所有更改都在一个单一的事务中进行处理。这样可以保证数据的一致性和完整性。
Repository(存储库)模式:这是一种设计模式,用于抽象对数据源的访问。它提供了一种统一的方式来查询和操作数据,而不需要关心底层的数据存储细节。
Entity Framework Core(EF Core):这是一个轻量级、可扩展且跨平台的ORM(对象关系映射)框架,用于.NET Core和.NET 5+应用程序。
以下是一个简单的UnitOfWork和Repository模式的实现,结合Entity Framework Core和单元测试。
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
public class AppDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("YourConnectionStringHere");
}
}
public interface IProductRepository
{
IEnumerable<Product> GetAll();
Product GetById(int id);
void Add(Product product);
void Update(Product product);
void Delete(int id);
}
public class ProductRepository : IProductRepository
{
private readonly AppDbContext _context;
public ProductRepository(AppDbContext context)
{
_context = context;
}
public IEnumerable<Product> GetAll()
{
return _context.Products.ToList();
}
public Product GetById(int id)
{
return _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);
}
}
}
public interface IUnitOfWork
{
IProductRepository ProductRepository { get; }
void Save();
}
public class UnitOfWork : IUnitOfWork
{
private readonly AppDbContext _context;
private IProductRepository _productRepository;
public UnitOfWork(AppDbContext context)
{
_context = context;
}
public IProductRepository ProductRepository
{
get
{
if (_productRepository == null)
{
_productRepository = new ProductRepository(_context);
}
return _productRepository;
}
}
public void Save()
{
_context.SaveChanges();
}
}
[TestClass]
public class UnitOfWorkTests
{
private AppDbContext _context;
private IUnitOfWork _unitOfWork;
[TestInitialize]
public void Initialize()
{
var options = new DbContextOptionsBuilder<AppDbContext>()
.UseInMemoryDatabase(databaseName: "TestDb")
.Options;
_context = new AppDbContext(options);
_unitOfWork = new UnitOfWork(_context);
}
[TestMethod]
public void AddProduct_ShouldAddProductToDatabase()
{
// Arrange
var product = new Product { Name = "Test Product", Price = 100 };
// Act
_unitOfWork.ProductRepository.Add(product);
_unitOfWork.Save();
// Assert
var addedProduct = _unitOfWork.ProductRepository.GetById(product.Id);
Assert.IsNotNull(addedProduct);
Assert.AreEqual("Test Product", addedProduct.Name);
Assert.AreEqual(100, addedProduct.Price);
}
}
原因:可能是由于数据库连接问题或事务配置不正确。
解决方法:确保数据库连接字符串正确,并在UnitOfWork中显式开启和提交事务。
public void Save()
{
using (var transaction = _context.Database.BeginTransaction())
{
try
{
_context.SaveChanges();
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
throw;
}
}
}
原因:可能是由于测试数据未正确清理或隔离。
解决方法:在每个测试方法执行前后清理数据库,确保测试数据隔离。
[TestCleanup]
public void Cleanup()
{
_context.Database.EnsureDeleted();
}
通过以上步骤,你可以有效地使用Entity Framework Core实现UnitOfWork和Repository模式,并进行单元测试。
领取专属 10元无门槛券
手把手带您无忧上云