Edit Revised after feedback.
public interface IRepositoryBase
{
int Delete<T>(T entity) where T : class;
void Dispose();
IQueryable<T> FindAllBy<T>(Expression<Func<T, bool>> predicate) where T : class;
T FindSingleBy<T>(Expression<Func<T, bool>> predicate) where T : class;
IQueryable<T> GetAll<T>() where T : class;
IQueryable<T> GetIncluding<T>(params Expression<Func<T, object>>[] includeProperties) where T:class;
int Save<T>(T Entity) where T : class;
int Update<T>(T Entity) where T : class;
}
public class RepositoryBase<TContext> : IDisposable, IRepositoryBase where TContext : DbContext,new()
{
private TContext _DataContext;
protected virtual TContext DataContext
{
get
{
if (_DataContext == null)
{
_DataContext = new TContext();
}
return _DataContext;
}
}
public virtual IQueryable<T> GetAll<T>() where T : class
{
using (DataContext)
{
return DataContext.Set<T>();
}
}
public virtual T FindSingleBy<T>(Expression<Func<T, bool>> predicate) where T : class
{
if (predicate != null)
{
using (DataContext)
{
return DataContext.Set<T>().Where(predicate).SingleOrDefault();
}
}
throw new ArgumentNullException("Predicate value must be passed to FindSingleBy<T>.");
}
public virtual IQueryable<T> FindAllBy<T>(Expression<Func<T, bool>> predicate) where T : class
{
if (predicate != null)
{
using (DataContext)
{
return DataContext.Set<T>().Where(predicate).AsQueryable<T>(); ;
}
}
throw new ArgumentNullException("Predicate value must be passed to FindBy<T,TKey>.");
}
public IQueryable<T> GetIncluding<T>(params Expression<Func<T, object>>[] includeProperties) where T: class
{
IQueryable<T> query = _DataContext.Set<T>();
foreach (var includeProperty in includeProperties)
{
query = query.Include(includeProperty);
}
return query;
}
public virtual int Save<T>(T Entity) where T : class
{
return DataContext.SaveChanges();
}
public virtual int Update<T>(T Entity) where T : class
{
return DataContext.SaveChanges();
}
public virtual int Delete<T>(T entity) where T : class
{
DataContext.Set<T>().Remove(entity);
return DataContext.SaveChanges();
}
public void Dispose()
{
if (DataContext != null) DataContext.Dispose();
}
}
Edit 2 :
I was writing tests against this using MOQ and NUnit. It fast turned into a nightmare of sorts. I went through the pain of my tests becoming dependent on EF. I do not think that is a good idea.Anyone have any ideas how to unit test RepositoryBase or as I see it I need to refactor and have a UnitOFWork. This has been a serious examination of my skills.
Edit 3 :
https://gist.github.com/4175430 I have put my new code there just the outline not the details inside . Now I am struggling with the ability to test this. I know the integration tests with a live db will give me the idea about Linq2Entities since testing this using Linq2Objects doesn't really make any sense.
With the answers mentioned below it seems like I need to have a service layer and my tests will have to be against this layer and not the repository since I should trust Microsoft with testing EF in the first place.