• Code
  • Tags
  • Users
  • Titles
  • Log in
  • Feedback
  • FAQ
Share Code
Welcome to ForkCan.com

ForkCan is all about sharing code in a social way.

Discuss, debate or argue with other devs about their or your own code.

Give other devs feedback or make a Fork (Make a better version of a shared code).

Rate the code, if you use the code mark it as used so others can see if the shared code is used by someone.

Help each other to be better devs and to be more productive.


Features not working yet:

Flag a post


QR Code

Tiny Url

http://4kcan.com/s/MTgw

Related Code
Generic Entity Framework 4.0 Base Repository
Loading Strategy for Entity Framework 4.0
Keep Entity Framework ObjectContext in a WCF Service OperationContext
Generic linq-to-sql repository
A Default Entity Framework 4.0 ObjectContext Factory
UnitOfWork Action filter for ASP.NET MVC and nHibernate
ForEach Extension method for IEnumerable<T>
Invoke Extension Method
Use of Extension methods to hide "infrastructure code"
Unity Service Locator for ASP.NET MVC 3.0 Beta 1
Null Dot "Operator" Extension Method
WCF RIA Services Unity 2.0 DomainService Factory
Make sure the web.config pages/namespace can be used together with ASP.NET MVC 3 P1 and Razor
Custom C# exception class
Email validation with Regular Expression
Reflection dynamically get private fields or properties
Url Validation with Regular Expression
Method to hash passwords
Number of sealed / unsealed types in the framework
Extension to the HttpClient

Generic Entity Framework 4.0 Base Repository with Paging

Fork of the Generic Entity Framework 4.0 Base Repository

1
2.29k 0 0 0 0 2

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);
    }
}

Share: twitter | facebook   Action: used | fork | flag

.net

Mark '.net' tag as 'like'

Mark '.net' tag as 'ignore'

c#

Mark 'c#' tag as 'like'

Mark 'c#' tag as 'ignore'

ef4.0

Mark 'ef4.0' tag as 'like'

Mark 'ef4.0' tag as 'ignore'

repository

Mark 'repository' tag as 'like'

Mark 'repository' tag as 'ignore'


 @CodingInsomnia "First one to share code"
349
July 12, 2010 10:43 PM
edited July 15, 2010 11:42 PM

Fork

 Generic Entity Framework 4.0 Base Repository -  @fredrikn Saturday 10, 2010 10:04 AM
 Generic Entity Framework 4.0 Base Repository with Paging -  @CodingInsomnia Monday 12, 2010 10:43 PM


0 Feedback


You must log in before you can give any feedback


2 Discussion(s)

Newest Oldest
1

Any reason why you use a separate Repository for paging?

link | flag  | Reply

 @fredrikn "I'm the master"
3.11k
Tuesday 13, 2010 1:14 PM

0

It's simply because I want to be able to choose if I need paging or not for each repository. If I don't need it, I'll use RepositoryBase as a base class, if I need it I'll use PagedRepositoryBase.

link | flag  | Reply

 @CodingInsomnia "First one to share code"
349
Tuesday 13, 2010 9:07 PM


You must log in before you can post a comment

Squeed
Made by: Fredrik Normén 2010