Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Implementation of the Repository and UnitOfWork pattern using Entity Framework.
// A generic base repository which other repositories (if needed) can inherit from
public class BaseRepository<TEntity> : IEntityRepository<TEntity> where TEntity : class
{
internal DataContext context;
internal DbSet<TEntity> dbSet;
public BaseRepository(DataContext context)
{
this.context = context;
this.dbSet = context.Set<TEntity>();
}
public virtual IEnumerable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, params Expression<Func<TEntity, object>>[] includeProperties)
{
IQueryable<TEntity> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties)
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
public virtual TEntity GetById(params object[] id)
{
return dbSet.Find(id);
}
public virtual void Insert(TEntity entity)
{
dbSet.Add(entity);
}
public virtual void Update(TEntity entityToUpdate)
{
dbSet.Attach(entityToUpdate);
context.Entry(entityToUpdate).State = EntityState.Modified;
}
public virtual void Delete(params object[] id)
{
TEntity entityToDelete = dbSet.Find(id);
Delete(entityToDelete);
}
public virtual void Delete(TEntity entityToDelete)
{
if (context.Entry(entityToDelete).State == EntityState.Detached)
{
dbSet.Attach(entityToDelete);
}
dbSet.Remove(entityToDelete);
}
}
//Interface that defines the basis of my repository classes
public interface IEntityRepository<T>
{
IEnumerable<T> Get(Expression<Func<T, bool>> filter = null,
Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null,
params Expression<Func<T, object>>[] includeProperties);
T GetById(params object[] id); //uses params keyword which allows searching tables with composite primary key.
void Insert(T entity);
void Update(T entityToUpdate);
//Deletes the object based on the primary key and uses params to support entities with composite primary key
void Delete(params object[] id);
}
public interface IUnitOfWork : IDisposable
{
IAccountRepository AccountRepository { get; }
void Save();
}
public class UnitOfWork : IUnitOfWork
{
private bool _disposed = false;
private DataContext _context = new DataContext();
private BaseRepository<User> userRepository;
private AccountRepository accountRepository;
public BaseRepository<User> UserRepository
{
get
{
if (this.userRepository == null)
{
this.userRepository = new GenericRepository<User>(_context);
}
return userRepository;
}
}
public IAccountRepository AccountRepository
{
get
{
if (this.accountRepository == null)
{
this.accountRepository = new AccountRepository(_context);
}
return accountRepository;
}
}
public void Save()
{
_context.SaveChanges();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this._disposed)
{
if (disposing)
{
_context.Dispose();
}
}
this._disposed = true;
}
//Sample controller class which also show how to use the include parameter options which i a linq query
public class UserController : Controller
{
private UnitOfWork unitOfWork = new UnitOfWork();
public ActionResult Index()
{
//example
var users = unitOfWork.UserRepository.Get(includeProperties: user => user.Followers);
foreach (var user in users)
{
//do something maybe
}
return View(users);
}
protected override void Dispose(bool disposing)
{
unitOfWork.Save();//Saves all unsaved result before disposing
unitOfWork.Dispose();
base.Dispose(disposing);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.