工作单元模式往往和仓储模式一起使用,本篇文章讲到的是工作单元模式和仓储模式一起用来在ef外面包一层,其实EF本身就是工作单元模式和仓储模式使用的经典例子,其中DbContext就是工作单元,而每个DbSet就是每个仓储,只有DbContext可以进行持久化操作。
那么我们为什么还要在EF的外面再包一层对EF进行封装呢,有时候也是需要这样做的根据需要我们可以把EF框架和业务逻辑分开以达到解耦的目的。便于以后在需要的时候用其他ORM框架代替EF。另外,如果只使用仓储模式,那么我们就会在每个仓储中进行持久化操作。这样做往往是不合理的,持久化的操作应当交给工作单元。
代码如下(代码是从网上找的例子)
public class EventsController : Controller{ private readonly ApplicationDbContext _context; private readonly UnitOfWork _unitOfWork; public EventsController() { _context = new ApplicationDbContext(); _unitOfWork = new UnitOfWork(_context); } public ActionResult Details(int id) { var event = _unitOfWork.Events.GetEvent(id); if (event == null) return HttpNotFound(); var viewModel = new EventDetailsViewModel { Event = event }; return View("Details", viewModel); } [Authorize] public ActionResult MyEvents() { var userId = User.Identity.GetUserId(); var events = _unitOfWork.Events.GetUpcomingEventsByArtist(userId); return View(events); } [Authorize] [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create(EventFormViewModel viewModel) { if (!ModelState.IsValid) { viewModel.Genres = _unitOfWork.Genres.GetGenres(); return View("EventForm", viewModel); } var event = new Event { ArtistId = User.Identity.GetUserId(), DateTime = viewModel.GetDateTime(), GenreId = viewModel.Genre, Venue = viewModel.Venue }; _unitOfWork.Events.Add(event); _unitOfWork.Complete(); return RedirectToAction("MyEvents", "Events"); }}
public class UnitOfWork{ private readonly ApplicationDbContext _context; public EventRepository Events { get; private set; } public GenreRepository Genres { get; private set; } public UnitOfWork(ApplicationDbContext context) { _context = context; Events = new EventRepository(context); Genres = new GenreRepository(context); } public void Complete() { _context.SaveChanges(); }}