Dofactory.com
Dofactory.com
 Back to list
Views:   24.8K
Replies:  3
Archived

Paging Support using Repository Pattern

I am new to Design Patterns and am working on a project based on the Patterns In Action 4.0 solution.  I am trying to implement paging support in an MVC web application and am having an issue.  The paging library I am using can be found in Stephen Walthers' MVC Unleashed book.  The library makes use of Linq Extensions to add the paging logic to the Entity framework query.

The issue I am having is when the Paging Linq Extension tries to count the number of records.  I get an error message that states "The ObjectContext instance has been disposed and can no longer be used for operations that require a connection".  I understand that the connection is closed since in the repository class the method utilizes a "using" statement.  After the query is complete the connection is closed.  What would be the best way to add paging support to the repository pattern?

Thanks

Paging code below:

public static class PagingLinqExtensions
{
  public static PagedList<T> ToPagedList<T>(this IQueryable<T> allItems, int? pageIndex, int pageSize)
  {
    return ToPagedList<T>(allItems, pageIndex, pageSize, string.Empty);
  }
  public static PagedList<T> ToPagedList<T>(this IQueryable<T> allItems, int? pageIndex, int pageSize, string sort)
  {
    var truePageIndex = pageIndex ?? 0;
    var itemIndex = truePageIndex * pageSize;
    var pageOfItems = allItems.Skip(itemIndex).Take(pageSize);
    var totalItemCount = allItems.Count();
    return new PagedList<T>(pageOfItems, truePageIndex, pageSize, totalItemCount, sort);
  }
}

Repository code below:

public IQueryable<Asset> GetAll()
{
  using (var context = DataObjectFactory.CreateContext())
  {
    return context.AssetEntities.Select(x => AssetMapper.ToBusinessObject(x));
  }
}

 
Mario Lopez, Aug 16, 2010
Reply 1
Hey King, I have looked at your tutorials earlier this year which is how I found out about dofactory.com.  I have also looked at the Telerik and MvcContrib libraries.  I was just trying to see how to add the paging support using the PagedList library.
Mario Lopez, Aug 31, 2010
Reply 2
Mario,

There are a number of solutions for this.  Mario is correct regarding the fact that you need to disconnect from the data context in order to make this work if you're not referencing your data context in your controller (which in my opinion you should never do).

A couple options would be:
  1. MvcContrib - this is a free framework that contains a Paging component.  You can find it at http://www.codeplex.com/mvccontrib/.
  2. Telerik ASP.NET MVC framework - this is a free (somewhat) framework that I've used that makes creating grids and handling paging easy.
You should take a look at a 13-episode video and article series where I build and MVC application from the ground up.

First Article in the series - http://www.mvccentral.net/Article/Details/3/Golf_Tracker_-_Pt_1_-_Overview
First Video in the series - http://www.mvccentral.net/Video/Details/2/Golf_Tracker_-_Pt_1_-_Overview

I hope they help.

King Wilder
King Wilder, Aug 27, 2010
Reply 3
In short, the issue here is the Unleashed code is relying on LINQ to SQL. When you mix in the D O Factory repository, you end up without a context that survives each hit.

One option I can think of is to add the idea of a disconnected context to your data access code, but this means divorcing the Unleashed code from the data completely. I have blogged about disconnected LINQ, but you can also find numerous Google hits on the subject.

Another option is to use LINQ, but not LINQ to SQL. This means pulling the entire object graph from the data store and then filtering. This can be expensive if you are paging through thousands of records, however, so be sensible. It can still be an option in a scalable system, but you will likely have to introduce a caching pattern so you are not hammering the data store with every page hit.

Ultimately, you end up with two patterns with paging (with some variations in between):

  1. Get all records and then filter (caching can work here to get some scalability)

  2. Get a full count and then only retrieve records for the page

There are options in between, but you either pull for a particular page or you pull everything and then filter for a page. There are some more complex patterns, as well, but I would try one of the above before heading into linked lists, etc.

Hope this helps.

Peace and Grace,
Greg

Twitter: @gbworld
Blog: http://gregorybeamer.spaces.live.com

Gregory Beamer, Aug 16, 2010
Stay Inspired!
Join other developers and designers who have already signed up for our mailing list.
Terms     Privacy     Cookies       Do Not Sell       Licensing      
Made with    in Austin, Texas.  - vsn 44.0.0
© Data & Object Factory, LLC.