Использование паттернов 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);
}
}
Комментариев нет:
Отправить комментарий