Использование паттернов Unit of work и Generic Repository c Entity Framework 5.0
Паттерн Unit of Work, по сути, нужен для консолидации всех методов, которые работают с базой данных. С его помощью можно улучшить контроль над изменением данных в БД, а также оптимизировать использование БД при обработке нескольких запросов одновременно. Использование Generic Repository упростит работу с EF Entities.
Создаем интерфейс IRepository, который описывает все необходимые операции с БД:
Теперь создадим класс GenericRepository, реализующий этот интерфейс:
Так как EF context реализует интерфейс IDisposable, то и UnitOfWork должен его реализовать. Тут показана всего одна конкретная реализация репозитория для сущности User, остальные репозитории добавляются аналогично. Для того чтобы постоянно работать с одним экземпляром Unit of Work в приложении ASP.NET MVC был создан BaseController, от которого будут наследоваться все остальные контроллеры:
Паттерн Unit of Work, по сути, нужен для консолидации всех методов, которые работают с базой данных. С его помощью можно улучшить контроль над изменением данных в БД, а также оптимизировать использование БД при обработке нескольких запросов одновременно. Использование Generic Repository упростит работу с EF Entities.
Создаем интерфейс IRepository, который описывает все необходимые операции с БД:
public interface IRepository<TEntity> where TEntity : class { IEnumerable<TEntity> Get(); TEntity GetById(object id); void Insert(TEntity entity); void Delete(object id); void Delete(TEntity entityToDelete); void Update(TEntity entityToUpdate); }
Теперь создадим класс GenericRepository, реализующий этот интерфейс:
public class GenericRepository<TEntity> : IRepository<TEntity> where TEntity : class { internal IntraWebEntities Context; internal DbSet<TEntity> DbSet; public GenericRepository(IntraWebEntities context) { Context = context; DbSet = context.Set<TEntity>(); } public virtual IEnumerable<TEntity> Get() { IQueryable<TEntity> query = DbSet; return query.ToList(); } public virtual TEntity GetById(object id) { return DbSet.Find(id); } public virtual void Insert(TEntity entity) { DbSet.Add(entity); } public virtual void Delete(object id) { TEntity entityToDelete = DbSet.Find(id); DbSet.Remove(entityToDelete); } public virtual void Delete(TEntity entityToDelete) { if (Context.Entry(entityToDelete).State == EntityState.Detached) { DbSet.Attach(entityToDelete); } DbSet.Remove(entityToDelete); } public virtual void Update(TEntity entityToUpdate) { DbSet.Attach(entityToUpdate); Context.Entry(entityToUpdate).State = EntityState.Modified; } }Теперь перейдем к созданию класса UnitOfWork:
public class GenericRepository<TEntity> : IRepository<TEntity> where TEntity : class { internal IntraWebEntities Context; internal DbSet<TEntity> DbSet; public class UnitOfWork : IDisposable { private readonly IntraWebEntities _context = new IntraWebEntities(); private IRepository<User> _userRepository; public IRepository<User> UserRepository { get { return _userRepository ?? (_userRepository = new GenericRepository<User>(_context)); } } public void Save() { _context.SaveChanges(); } private bool _disposed; protected virtual void Dispose(bool disposing) { if (!_disposed) { if (disposing) { _context.Dispose(); } } _disposed = true; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } }
Так как EF context реализует интерфейс IDisposable, то и UnitOfWork должен его реализовать. Тут показана всего одна конкретная реализация репозитория для сущности User, остальные репозитории добавляются аналогично. Для того чтобы постоянно работать с одним экземпляром Unit of Work в приложении ASP.NET MVC был создан BaseController, от которого будут наследоваться все остальные контроллеры:
public abstract class BaseController : Controller { private UnitOfWork _unitOfWork; public UnitOfWork UnitOfWork { get { return _unitOfWork ?? (_unitOfWork = new UnitOfWork()); } } }
public class UserController : BaseController { [AllowAnonymous] public ActionResult Index() { var users = UnitOfWork.UserRepository.Get().ToList(); return View(users); } }
Комментариев нет:
Отправить комментарий