Repository Pattern
From Logic Wiki
Reporsitory pattern is a layer between application and data storage. With this pattern application doesn't need to know how to delete, update or write data to database.
Contents
In a nutshell
- Get(id)
- GetAll()
- Find(predicate)
- Add(obj)
- AddRange(obj)
- Remove(obj)
- RemoveAll(obj)
Sample pattern
Interface
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace Queries.Core.Repositories
{
public interface IRepository<TEntity> where TEntity : class
{
TEntity Get(int Id);
IEnumerable<TEntity> GetAll();
IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);
void Add(TEntity entity);
void AddRange(IEnumerable<TEntity> entities);
void Remove(TEntity entity);
void RemoveAll(IEnumerable<TEntity> entities);
}
}
Generic Implementation
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using Spv.Api.Core.IDataAccess;
namespace Spv.Api.Core.DataAccess
{
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected readonly DbContext Context;
public Repository(DbContext context)
{
Context = context;
}
public TEntity Get(int Id)
{
return Context.Set<TEntity>().Find(Id);
}
public IEnumerable<TEntity> GetAll()
{
return Context.Set<TEntity>().ToList();
}
public IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate)
{
return Context.Set<TEntity>().Where(predicate);
}
public void Add(TEntity entity)
{
Context.Set<TEntity>().Add(entity);
}
public void AddRange(IEnumerable<TEntity> entities)
{
Context.Set<TEntity>().AddRange(entities);
}
public void Remove(TEntity entity)
{
Context.Set<TEntity>().Remove(entity);
}
public void RemoveAll(IEnumerable<TEntity> entities)
{
Context.Set<TEntity>().RemoveRange(entities);
}
}
}
Custom Repository Interface
using System.Collections.Generic;
using Spv.Api.Models;
using Spv.Models;
namespace Spv.Api.Core.IDataAccess
{
public interface IDealRepository : IRepository<Deal>
{
IEnumerable<DealModel> GetAllDealModels();
DealModel GetDealModelById(int id);
}
}
Custom Repository
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Spv.Api.Core.IDataAccess;
using Spv.Api.Models;
using Spv.Models;
namespace Spv.Api.Core.DataAccess
{
public class DealRepository : Repository<Deal>, IDealRepository
{
public DealRepository(SpvDbContext context) : base(context)
{
}
IEnumerable<DealModel> IDealRepository.GetAllDealModels()
{
return SpvDbContext.Deals.Select(x=> new DealModel(x)).ToList();
}
public DealModel GetDealModelById(int id)
{
var deal = SpvDbContext.Deals.FirstOrDefault(x => x.Id == id);
return deal == null ? null : new DealModel(deal);
}
public SpvDbContext SpvDbContext
{
get { return Context as SpvDbContext;}
}
}
}
useful paging sample which can be implemented in custom repository
public IEnumerable<Deal> GetSomeDeals(int pageIndex, int pagesSize = 10)
{
return SpvDbContext.Deals
.Include(c => c.Author)
.OrderBy(c => c.Name)
.Skip((pageIndex - 1) * pageSize)
.Take(pageSize)
.ToList();
}
Generic Repository Pattern
See Also : Unit Of Work Pattern