如何用仓储实现事务?
如何处理多个Repository库?
借用一段话:
下面想象下如下场景,我们数据库中有多个表,那样我们需要为每个表创建一个Reporsitory类。(好多重复工作的说,其实这不是问题)
问题是关于 数据上下文(DbContext) 对象的。如果我们创建多个Repository类,是不是每一个都单独的包含一个 数据上下文对象?我们知道同时使用多个 数据上下文 会存在问题,那我们该怎么处理每个Repository都拥有自己的数据上下文 对象的问题?
来解决这个问题吧。为什么每个Repository要拥有一个数据上下文的实例呢?为什么不在一些地方创建一个它的实例,然后在repository被实例化的时候作为参数传递进去呢。现在这个新的类被命名为 UnitOfWork ,此类将负责创建数据上下文实例并移交到控制器的所有repository实例。
先看整理的类图:
项目文件结构:
UnitWork代码:
namespace Contacts.Repository.Infrastructure
{
public class UnitOfWork : IUnitOfWork
{
private TransactionScope _transaction;
private readonly ZHDbContext _db;
public UnitOfWork()
{
_db = new ZHDbContext();
}
public void Dispose()
{
}
public void StartTransaction()
{
_transaction = new TransactionScope(); //实例化上下文
}
public void Commit()
{
_db.SaveChanges();
_transaction.Complete();
}
public DbContext Db
{
get { return _db; }
}
}
}
BaseRepository代码片段
/// <summary>
/// Repository资源库基础实现
/// </summary>
/// <typeparam name="T"></typeparam>
public class BaseRepository<T> : IBaseRepository<T> where T : class, new()
{
private DbContext db;//原来的
private readonly IUnitOfWork _unitOfWork;
internal DbSet<T> dbSet;
public BaseRepository(IUnitOfWork unitOfWork)
{
//创建上下文
db = DbContextHelper.GetZHDbContext<ZHDbContext>();//原来的
if (unitOfWork == null) throw new ArgumentNullException("unitOfWork");
_unitOfWork = unitOfWork;
this.dbSet = _unitOfWork.Db.Set<T>();
}
...
public IQueryable<T> GetAll()
{
return _unitOfWork.Db.Set<T>();
}
...
}
StudentRepository代码: /// <summary>
/// 业务逻辑实现层
/// </summary>
public class StudentRepository : BaseRepository<Student>, IStudentRepository
{
public StudentRepository(IUnitOfWork unit):base(unit)
{
}
}
其他分层代码同上文
controller调用:
public class StudentsController : Controller
{
private IUnitOfWork uow = null;
private StudentRepository repo = null;
//IStudentService _studentService; 原来的代码
public StudentsController()
{
// _studentService = new StudentService();
uow = new UnitOfWork();
repo = new StudentRepository(uow);
}
// public IStudentService _studentService { get; set; }原来的代码
//GET: Students
public ActionResult Index()
{
var model = repo.GetAll().ToList();
return View(model);
}
...
}
可参考代码运行效果:
本文代码是个逐步演进的过程,所以部分代码做了测试,依旧http://localhost:59148/Students/Index测试通过
本文参考网址:
https://www.codeproject.com/Articles/688929/Repository-Pattern-and-Unit-of
本文源代码地址:
http://download.youkuaiyun.com/download/wenxi2367/10195376