dynamic sorting expression builder

來源:互聯網
上載者:User
代碼 public static class Paging
    {
        public interface ISortbyBuilder<TSource>
        {   
            IQueryable<TSource> SortBy(IQueryable<TSource> obj, LambdaExpression keySelector, bool asc);
        }

        public class SortbyBuilder<TSource, TKey> : ISortbyBuilder<TSource>
        {
            public IQueryable<TSource> SortBy(IQueryable<TSource> obj, LambdaExpression keySelector, bool asc)
            {
                var castedKeySelector = (Expression<Func<TSource, TKey>>) keySelector;
                return asc ? obj.OrderBy(castedKeySelector) : obj.OrderByDescending(castedKeySelector);
            }
        }

        public class SortbyBuilderCache<TSource>
        {
            private static readonly IDictionary<Type, ISortbyBuilder<TSource>> Cache = new Dictionary<Type, ISortbyBuilder<TSource>>();

            public static IQueryable<TSource> SortBy(IQueryable<TSource> obj, LambdaExpression keySelector, bool asc)
            {
                // TODO: I told you this is magic!
                var selectorReturnType = keySelector.Body.Type;
                ISortbyBuilder<TSource> sortbyBuilder;
                if (!Cache.TryGetValue(selectorReturnType, out sortbyBuilder))
                {
                    var typeArguments = new[] { typeof(TSource), selectorReturnType };
                    var builderType = typeof(SortbyBuilder<,>).MakeGenericType(typeArguments);
                    sortbyBuilder = (ISortbyBuilder<TSource>)Activator.CreateInstance(builderType);
                }
                return sortbyBuilder.SortBy(obj, keySelector, asc);
            }
        }

        public static IPagination<T> AsPagination<T>(this IQueryable<T> obj, int pageNumber, int pageSize, string sortExpression)
        {
            sortExpression = sortExpression ?? string.Empty;
            var asc = !sortExpression.Contains("DESC");

            var sortKey = sortExpression.Split(' ')[0];

            if (string.IsNullOrEmpty(sortKey) || TypeDescriptor.GetProperties(typeof (T)).Find(sortKey, false) == null)
            {
                return obj.AsPagination(pageNumber, pageSize);
            }

            // TODO: magic
            var parameterExpression = Expression.Parameter(typeof (T));
            var propertyExpression = Expression.Property(parameterExpression, sortKey);
            LambdaExpression lambdaExpression;
            if (typeof (IEnumerationWrapper).IsAssignableFrom(propertyExpression.Type))
            {
                var valueExpression = Expression.Property(propertyExpression, "Value");
                lambdaExpression = Expression.Lambda(valueExpression, new[] {parameterExpression});
            }
            else
            {
                lambdaExpression = Expression.Lambda(propertyExpression, new[] {parameterExpression});
            }

            return SortbyBuilderCache<T>.SortBy(obj, lambdaExpression, asc).AsPagination(pageNumber, pageSize);

        }

        public static IPagination<T> AsPagination<T, TKey>(this IQueryable<T> obj, int pageNumber, int pageSize, Expression<Func<T, TKey>> keySelector, bool asc)
        {
            return asc ? obj.OrderBy(keySelector).AsPagination(pageNumber, pageSize) : obj.OrderByDescending(keySelector).AsPagination(pageNumber, pageSize);
        }
    }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.