Asp.net Core 源码-PagedList<T>

using System.Collections.Generic;
using System.Linq;
using System;
using System.Linq.Expressions;
using System.Diagnostics;

namespace SportsStore.Models.Pages {

    public class PagedList<T> : List<T> {

        public PagedList(IQueryable<T> query, QueryOptions options = null) {
            CurrentPage = options.CurrentPage;
            PageSize = options.PageSize;
            Options = options;

            if (options != null) {
                if (!string.IsNullOrEmpty(options.OrderPropertyName)) {
                    query = Order(query, options.OrderPropertyName, 
                        options.DescendingOrder);
                }
                if (!string.IsNullOrEmpty(options.SearchPropertyName) 
                        && !string.IsNullOrEmpty(options.SearchTerm)) {
                    query = Search(query, options.SearchPropertyName, 
                        options.SearchTerm);
                }
            }

            //Stopwatch sw = Stopwatch.StartNew();
            //Console.Clear();

            TotalPages = query.Count() / PageSize;
            AddRange(query.Skip((CurrentPage - 1) * PageSize).Take(PageSize));

            //Console.WriteLine($"Query Time: {sw.ElapsedMilliseconds} ms");
        }

        public int CurrentPage { get; set; }
        public int PageSize { get; set; }
        public int TotalPages { get; set; }
        public QueryOptions Options { get; set; }

        public bool HasPreviousPage => CurrentPage > 1;
        public bool HasNextPage => CurrentPage < TotalPages;

        private static IQueryable<T> Search(IQueryable<T> query, string propertyName, 
                string searchTerm) {
            var parameter = Expression.Parameter(typeof(T), "x");
            var source = propertyName.Split('.').Aggregate((Expression) parameter, 
                Expression.Property);
            var body = Expression.Call(source, "Contains", Type.EmptyTypes, 
                Expression.Constant(searchTerm, typeof(string)));
            var lambda = Expression.Lambda<Func<T, bool>>(body, parameter);
            return query.Where(lambda);
        }

        private static IQueryable<T> Order(IQueryable<T> query, string propertyName, 
                bool desc) {
            var parameter = Expression.Parameter(typeof(T), "x");
            var source = propertyName.Split('.').Aggregate((Expression) parameter, 
                Expression.Property);
            var lambda = Expression.Lambda(typeof(Func<,>).MakeGenericType(typeof(T), 
                source.Type), source, parameter);
            return typeof(Queryable).GetMethods().Single(
                      method => method.Name == (desc ? "OrderByDescending" 
                                  : "OrderBy")
                      && method.IsGenericMethodDefinition
                      && method.GetGenericArguments().Length == 2
                      && method.GetParameters().Length == 2)
                  .MakeGenericMethod(typeof(T), source.Type)
                  .Invoke(null, new object[] { query, lambda }) as IQueryable<T>;
        }
    }
}

 

public PagedList<Category> GetCategories(QueryOptions options) {
            return new PagedList<Category>(context.Categories, options);
        }

 

namespace SportsStore.Models.Pages {

    public class QueryOptions {

        public int CurrentPage { get; set; } = 1;
        public int PageSize { get; set; } = 10;

        public string OrderPropertyName { get; set; }
        public bool DescendingOrder { get; set; }

        public string SearchPropertyName { get; set; }
        public string SearchTerm { get; set; }
    }
}

 

posted @ 2019-06-22 20:32  接云网络  阅读(616)  评论(0编辑  收藏  举报