編輯:實體框架似乎是問題,在問題Entity Framework & Linq performance problem中進一步討論。Linq分頁 - 如何解決性能問題?
我支持一個長期離開的人編寫的PagedList類(使用linq/generics) - 它有2行非常糟糕的表現 - 對於只有2000行的數據集,它需要長達一分鐘的運行時間。
兩個問題的線路有:
TotalItemCount = source.Count();
我大概可以在數作爲參數傳遞解決這個問題。但是其他的線是慢在這個片段中AddRange
:
IQueryable<T> a = source.Skip<T>((index) * pageSize).Take<T>(pageSize);
AddRange(a.AsEnumerable());
我不明白爲什麼AddRange
是如此緩慢或者我能做些什麼來改善呢?
全班源列表
public class PagedList<T> : List<T>, IPagedList<T>
{
public PagedList(IEnumerable<T> source, int index, int pageSize)
: this(source, index, pageSize, null)
{
}
public PagedList(IEnumerable<T> source, int index, int pageSize, int? totalCount)
{
Initialize(source.AsQueryable(), index, pageSize, totalCount);
}
public PagedList(IQueryable<T> source, int index, int pageSize)
: this(source, index, pageSize, null)
{
}
public PagedList(IQueryable<T> source, int index, int pageSize, int? totalCount)
{
Initialize(source, index, pageSize, totalCount);
}
#region IPagedList Members
public int PageCount { get; private set; }
public int TotalItemCount { get; private set; }
public int PageIndex { get; private set; }
public int PageNumber { get { return PageIndex + 1; } }
public int PageSize { get; private set; }
public bool HasPreviousPage { get; private set; }
public bool HasNextPage { get; private set; }
public bool IsFirstPage { get; private set; }
public bool IsLastPage { get; private set; }
#endregion
protected void Initialize(IQueryable<T> source, int index,
int pageSize, int? totalCount)
{
//### argument checking
if (index < 0)
{
throw new ArgumentOutOfRangeException("PageIndex cannot be below 0.");
}
if (pageSize < 1)
{
throw new ArgumentOutOfRangeException("PageSize cannot be less than 1.");
}
//### set source to blank list if source is null to prevent exceptions
if (source == null)
{
source = new List<T>().AsQueryable();
}
//### set properties
if (!totalCount.HasValue)
{
TotalItemCount = source.Count();
}
PageSize = pageSize;
PageIndex = index;
if (TotalItemCount > 0)
{
PageCount = (int)Math.Ceiling(TotalItemCount/(double)PageSize);
}
else
{
PageCount = 0;
}
HasPreviousPage = (PageIndex > 0);
HasNextPage = (PageIndex < (PageCount - 1));
IsFirstPage = (PageIndex <= 0);
IsLastPage = (PageIndex >= (PageCount - 1));
//### add items to internal list
if (TotalItemCount > 0)
{
IQueryable<T> a = source.Skip<T>((index) * pageSize).Take<T>(pageSize);
AddRange(a.AsEnumerable());
}
}
}
數據來自哪裏? PS:「我不明白爲什麼AddRange很慢」---「AddRange」不慢,但延遲linq表達式評估速度很慢。 – zerkms 2010-09-01 03:28:42
@zerkms對不起,它的a.AsEnumerable()很慢,而不是AddRange – 2010-09-01 03:30:23
@robert它被這樣調用:'var pagedModel = new PagedList(data,currentPage - 1,rowsPerPage);'PagedList inherits List ,所以'AddRange'和'this.AddRange'是一樣的。不是說我明白我的代碼100%自己 –
2010-09-01 03:33:38