Search code examples
c#asp.netuser-controls

How to use Skip() and Take() with IQueryable


I have a user control that contains a repeater and it's datasouce is set using an IEnumerable object that contains data returned from query in code. The repeater has paging functionality and displays a custom number of records for each page.

I don't want to load all the data each time the user clicks the next button to see the next page of records in the repeater. How can I make it IQueryable and use Skip() and Take() to display only the records needed for that page?

I have the following code:

//Code that assigns query to repeater data source
DataSet = QueryGoesHere.ToArray(); // returns IEnumerable
repeater.DataSource = DataSet;
repeater.DataBind();

//Code that creates PagedDataSource - how can I update this to make it display only the records that are needed for the currently displayed page?

            objPds = new PagedDataSource();
            objPds.DataSource = DataSource
            objPds.AllowPaging = true;
            objPds.PageSize = 5;
            objPds.CurrentPageIndex = CurrentPage;
            lblCurrentPage.Text = "Page: " + (CurrentPage + 1).ToString() + " of " + objPds.PageCount.ToString();

Solution

  • if I get you right you want to use your own implementation istead of loading all data and then using the PagedDataSource right?

    If so you have to make sure that QueryGoesHere is a Queryable supporting this (Linq2Sql or EF). Then you have to get the count of your date like this

    var count = QueryGoesHere.Count();
    

    and get the portion of data you want to display:

    var skip = (curPageNumber - 1)*itemsPerPage;
    var display = Math.Min(count - skip, itemsPerPage);
    

    and just use

    var displayedItems = QueryGoesHere.Skip(skip).Take(display).ToArray();
    

    That should do the trick.