I've forked the original and made a few changes. I've also added a base class that implements a simple paging scheme on top of the old class.
Interfaces
I've removed the GetQuery from the old interface. It is now a protected member of the base class. I've also added a new method that allows for results to be ordered
public interface IRepository<TEntity>
where TEntity : class
{
IEnumerable<TEntity> GetAll();
IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> whereClause);
IEnumerable<TEntity> Find<TKey>(Expression<Func<TEntity, bool>> whereClause,
Expression<Func<TEntity, TKey>> orderByClause);
TEntity Single(Expression<Func<TEntity, bool>> whereClause);
void Add(TEntity entity);
void Delete(TEntity entity);
}
The paged interface adds new methods that accepts a page number
public interface IPagedRepository<TEntity> : IRepository<TEntity>
where TEntity : class
{
IEnumerable<TEntity> GetAll(int pageNo);
IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> whereClause, int pageNo);
IEnumerable<TEntity> Find<TKey>(Expression<Func<TEntity, bool>> whereClause,
Expression<Func<TEntity, TKey>> orderByClause, int pageNo);
}
Base classes
Changed the name to RepositoryBase (I just prefer that naming scheme). I also always ensure to evaluate the query before handing it over to the caller (with ToArray). This could certainly be argued if it's a good idea or not.
public class RepositoryBase<TEntity> : IRepository<TEntity>
where TEntity : class
{
private readonly IObjectSet<TEntity> _objectSet;
public RepositoryBase(ObjectContext objectContext)
{
_objectSet = objectContext.CreateObjectSet<TEntity>();
}
// This property can be used by base classes
protected IQueryable<TEntity> Query { get { return _objectSet; } }
public virtual IEnumerable<TEntity> GetAll()
{
return Query.ToArray(); // What's best? ToList or ToArray?
}
public virtual IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> whereClause)
{
return Query.Where(whereClause).ToArray();
}
public virtual IEnumerable<TEntity> Find<TKey>(Expression<Func<TEntity, bool>> whereClause, Expression<Func<TEntity,TKey>> orderByClause)
{
return Query.Where(whereClause).OrderBy(orderByClause).ToArray();
}
public virtual TEntity Single(Expression<Func<TEntity, bool>> whereClause)
{
return Query.Where(whereClause).FirstOrDefault();
}
public virtual void Add(TEntity entity)
{
_objectSet.AddObject(entity);
}
public virtual void Delete(TEntity entity)
{
_objectSet.DeleteObject(entity);
}
}
In the paged base class I've overridden the base classes Get/Find methods so that they only return the first page. Maybe not always what you want, but my reasoning is that the client probably shouldn't be able to just ignore the paging.
public abstract class PagedRepositoryBase<TEntity> : RepositoryBase<TEntity>, IPagedRepository<TEntity>
where TEntity : class
{
private readonly int _pageSize;
protected PagedRepositoryBase(ObjectContext objectContext, int pageSize) : base(objectContext)
{
_pageSize = pageSize;
}
/// <summary>
/// This must be overridden in the base classes in order to provide the default sort order
/// for the entity. This is needed for paging to work
/// </summary>
protected abstract IOrderedQueryable<TEntity> GetDefaultOrder(IQueryable<TEntity> query);
public override IEnumerable<TEntity> GetAll()
{
// Only return the first page of entities
return GetAll(1);
}
public override IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> whereClause)
{
// Only return the first page of entities
return Find(whereClause, 1);
}
public override IEnumerable<TEntity> Find<TKey>(Expression<Func<TEntity, bool>> whereClause, Expression<Func<TEntity, TKey>> orderByClause)
{
// Only return the first page of entities
return Find(whereClause, orderByClause, 1);
}
public virtual IEnumerable<TEntity> GetAll(int pageNo)
{
return GetDefaultOrder(Query).Skip((pageNo - 1) * _pageSize).Take( _pageSize ).ToArray();
}
public virtual IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> whereClause, int pageNo)
{
var entities = GetDefaultOrder(Query.Where(whereClause)).Skip((pageNo - 1) * _pageSize).Take( _pageSize );
return entities.ToArray();
}
public virtual IEnumerable<TEntity> Find<TKey>(Expression<Func<TEntity, bool>> whereClause, Expression<Func<TEntity, TKey>> orderByClause, int pageNo)
{
var entities = Query.Where(whereClause).OrderBy(orderByClause).Skip((pageNo - 1) * _pageSize).Take( _pageSize );
return entities.ToArray();
}
}
Sample repository
And finally, a sample of an implementation of the PagedRepository
public class PersonRepository : PagedRepositoryBase<Person>
{
public PersonRepository(ObjectContext objectContext, int pageSize)
: base(objectContext, pageSize)
{
}
protected override IOrderedQueryable<Person> GetDefaultOrder(IQueryable<Person> query)
{
return query.OrderBy(p => p.LastName);
}
}
Fork
0 Feedback
You must log in before you can give any feedback
You must log in before you can post a comment


2.29k
0




Mark '.net' tag as 'like'
Mark '.net' tag as 'ignore'