I have some problems with a slow query in Entity Framework in C#. I have created an extension method called Page to handle paging, but when I use it the query gets really slow. If I just do .Skip(page.Value * pageSize.Value).Take(pageSize.Value) instead of using Page the query gets a lot faster. I guess that doing it with Page fetches all contacts before paging. Is there a way to prevent this or am I doing something else wrong?
Query:
var contacts = db.Contacts
.Where(x => x.AccountID == accountID && x.Deleted == false)
.OrderByDescending(x => x.FirstName)
.ThenBy(x => x.LastName)
.ThenBy(x => x.CreatedDate)
.Page(page, pageSize);
return contacts.ToList();
Extension method:
public static IEnumerable<T> Page<T>(this IEnumerable<T> elements, int? page, int? pageSize)
{
if (page.HasValue && pageSize.HasValue)
return elements.Skip(page.Value * pageSize.Value).Take(pageSize.Value);
else
return elements;
}
Your extension method should be over IQueryable so that EF can process the expression and generate the SQL query with pagination.
Since your using IEnumerable, the Page method will invoke Skip and Take of IEnumerable. This will cause enumeration of the result of the query that was built up to that point (before the call to Page) and make the pagination in memory, over all the returned items, instead of including pagination on the DB query.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With