/// <summary>
        /// Generalized Queryable search that supports filtering and paging
        /// </summary>
        /// <param name="filter">filter expression</param>
        /// <param name="pageRequest">page request</param>
        /// <param name="ct">cancellation token</param>
        /// <returns>search results</returns>
        protected async Task <IPageResult <TModel> > OnGeneralizedSearch(Expression <Func <TModel, bool> > filter, IPageRequest pageRequest, CancellationToken ct)
        {
            var result = new PageResult <TModel>
            {
                PageNumber = 1,
            };

            var query = this.OnQueryable(ct);

            // add filter expression to query
            if (filter != null)
            {
                var expression = this.DataMapper.MapExpression <Expression <Func <TEntity, bool> > >(filter);
                query = query.Where(expression);
            }

            // add paging expression to query
            if (pageRequest != null)
            {
                result.PageNumber = pageRequest.PageNumber;

                query = query.Skip(pageRequest.SkipAmount())
                        .Take(pageRequest.TakeAmount());

                if (pageRequest.IncludeTotalCount)
                {
                    await this.CountEntityAsync(result, query, ct)
                    .ConfigureAwait(false);
                }
            }

            var entitySet = query.ToList();

            result.Items = this.OnConvert(entitySet);

            return(result);
        }