private static async Task <PaginatedItem <TResponse> > GetDataAsync <TDbContext, TEntity, TResponse>( IEfQueryRepository <TDbContext, TEntity> repo, Criterion criterion, Expression <Func <TEntity, TResponse> > selector, Expression <Func <TEntity, bool> > filter = null, params Expression <Func <TEntity, object> >[] includeProperties) where TDbContext : DbContext where TEntity : class, IEntity { if (criterion.PageSize < 1 || criterion.PageSize > criterion.DefaultPagingOption.PageSize) { criterion.SetPageSize(criterion.DefaultPagingOption.PageSize); } var queryable = repo.Queryable(); if (includeProperties != null && includeProperties.Count() > 0) { queryable = includeProperties.Aggregate( queryable, (current, include) => current.Include(include)); } if (filter != null) { queryable = queryable.Where(filter); } if (!string.IsNullOrWhiteSpace(criterion.SortBy)) { var isDesc = string.Equals(criterion.SortOrder, "desc", StringComparison.OrdinalIgnoreCase) ? true : false; queryable = queryable.OrderByPropertyName(criterion.SortBy, isDesc); } var results = await queryable .Skip(criterion.CurrentPage *criterion.PageSize) .Take(criterion.PageSize) .AsNoTracking() .Select(selector) .ToListAsync(); var totalRecord = await queryable.CountAsync(); var totalPages = (int)Math.Ceiling((double)totalRecord / criterion.PageSize); if (criterion.CurrentPage > totalPages) { criterion.SetCurrentPage(totalPages); } return(new PaginatedItem <TResponse>(totalRecord, totalPages, results)); }