How to use DataPager with Database Paged

后端 未结 2 1960
长情又很酷
长情又很酷 2021-01-06 08:17

I am using ListView/DataPager.

For performance reasons I page my results at database, using ROW_NUMBER(SQl2005).

At my C# code just comes one page at time. H

相关标签:
2条回答
  • 2021-01-06 09:11

    I created a class that gerenate fake default(T) objects. Worked fine:

    public class PagedList<T> : IEnumerable<T>, ICollection
    {
        private IEnumerable<T> ActualPage { get; set; }
        private int Total { get; set; }
        private int StartIndex { get; set; }
    
        public PagedList(int total, int startIndex, IEnumerable<T> actualPage)
        {
            ActualPage = actualPage;
            Total = total;
            StartIndex = startIndex;
        }
    
        public IEnumerator<T> GetEnumerator()
        {
            bool passouPagina = false;
            for (int i = 0; i < Total; i++)
            {
                if (i < StartIndex || passouPagina)
                {
                    yield return default(T);
                }
                else
                {
                    passouPagina = true;
                    foreach (T itempagina in ActualPage)
                    {
                        i++;
                        yield return itempagina;
                    }
                }
            }
        }
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    
        #region Implementation of ICollection
    
        void ICollection.CopyTo(Array array, int index)
        {
            throw new NotSupportedException();
        }
    
        public int Count
        {
            get { return Total; }
        }
    
        object ICollection.SyncRoot
        {
            get { throw new NotSupportedException(); }
        }
    
        bool ICollection.IsSynchronized
        {
            get { throw new NotSupportedException(); }
        }
    
        #endregion
    }
    

    Usage example:

    int totalRows = DB.GetTotalPeople();
    int rowIndex = (currentPage-1)*pageSize;
    List<Person> peoplePage = DB.GetPeopleAtPage(currentPage);
    
    listview.DataSource = new PagedList(totalRows, rowIndex, peoplePage)
    listView.DataBind();
    
    0 讨论(0)
  • 2021-01-06 09:15

    Apparently I can't comment on the above solution, that was provided by Fujiy, however I discovered the following bug:

    Inside GetEnumerator() the incrementation in the else branch will always cause the collection to skip one default element, unless you're on the last page of the PagedList.

    As an example, if you would create a paged list of 5 elements, with startindex 3 and 1 element per page. This could would enter the else branch for element 2. It would increment i to 3 and then go back into the for-header where it would increment to 4, without creating a default element for i == 3.

    • i == 1 -> default
    • i == 2 -> default
    • i == 3 -> Actual element
    • i == 4 -> Skipped
    • i == 5 -> default

    A simple solution would be to either use 3 for-loops (one for defaults before the ActualPage, one for the ActualPage and one for elements after the ActualPage). Or to add a i-- after the For-loop inside the Else-branch.

    0 讨论(0)
提交回复
热议问题