EF Code First Generic Repository
Arguably DbSet (or at least IDbSet) is minimal enough to use directly, but here's a generic repository that hides the EF dependency. It's based on the Nuget MvcScaffolding repository template and this asp.net tutorial.
The AddOrUpdate and Delete method use DbContext Extensions.
using System;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
namespace Domain
{
public class GenericRepository<T> : IGenericRepository<T>
where T : class
{
readonly DbContext _context;
public GenericRepository(DbContext context)
{
_context = context;
}
public IQueryable<T> Get
{
get { return _context.Set<T>(); }
}
public IQueryable<T> GetIncluding(params Expression<Func<T, object>>[] includeProperties)
{
IQueryable<T> query = _context.Set<T>();
foreach (var includeProperty in includeProperties)
{
query = query.Include(includeProperty);
}
return query;
}
public T Find(object[] keyValues)
{
return _context.Set<T>().Find(keyValues);
}
public void Add(T entity)
{
_context.Set<T>().Add(entity);
}
public void Update(T entity)
{
var entry = _context.Entry(entity);
if (entry.State == EntityState.Detached)
{
_context.Set<T>().Attach(entity);
entry = _context.Entry(entity);
}
entry.State = EntityState.Modified;
}
public void AddOrUpdate(T entity)
{
//uses DbContextExtensions to check value of primary key
_context.AddOrUpdate(entity);
}
public void Delete(object[] keyValues)
{
//uses DbContextExtensions to attach a stub (or the actual entity if loaded)
var stub = _context.Load<T>(keyValues);
_context.Set<T>().Remove(stub);
}
}
}
Interface
using System;
using System.Linq;
using System.Linq.Expressions;
namespace Domain
{
public interface IGenericRepository<T> where T : class
{
IQueryable<T> Get { get; }
IQueryable<T> GetIncluding(params Expression<Func<T, object>>[] includeProperties);
T Find(object[] keyValues);
void Add(T entity);
void Update(T entity);
void AddOrUpdate(T entity);
void Delete(object[] keyValues);
}
}