jueves, 17 de septiembre de 2015

Sort.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Migration.Target.Dao.Entities;
using System.Linq.Expressions;
using System.ComponentModel;

namespace Migration.Target.Dao.Filters
{
    public sealed class Sort<TEntity>
        where TEntity : Entity
    {
        private class SortField
        {
            public LambdaExpression Property { get; set; }
            public ListSortDirection Direction { get; set; }
        }

        private Queue<SortField> Fields { get; set; }

        internal Sort()
            : base()
        {
            this.Fields = new Queue<SortField>();
        }

        internal IQueryable<TEntity> BuildSortBy(IQueryable<TEntity> query)
        {
            bool flag = false;

            while (this.Fields.Any())
            {
                string method = string.Empty;
                SortField order = this.Fields.Dequeue();
                if (flag == false)
                {
                    if (order.Direction == ListSortDirection.Ascending)
                        method = "OrderBy";
                    else
                        method = "OrderByDescending";
                }
                else
                {
                    if (order.Direction == ListSortDirection.Ascending)
                        method = "ThenBy";
                    else
                        method = "ThenByDescending";
                }
                flag = true;

                MethodCallExpression methodCallExpression
                    = Expression.Call(
                        typeof(Queryable),
                        method,
                        new Type[] { query.ElementType, order.Property.Body.Type },
                        new[] { query.Expression, Expression.Quote(order.Property) }
                    );

                query = query.Provider.CreateQuery<TEntity>(methodCallExpression);
            }

            return query;
        }

        private void InternalAddSort(LambdaExpression expression, ListSortDirection direction)
        {
            this.Fields.Enqueue(new SortField() { Property = expression, Direction = direction });
        }

        public void AddSort<TValue>(Expression<Func<TEntity, TValue>> expression, ListSortDirection direction)
        {
            this.InternalAddSort(expression, direction);
        }

        public void AddSort(string field, ListSortDirection direction)
        {
            ParameterExpression ent = Expression.Parameter(typeof(TEntity));

            Expression par = ent;
            Expression bod = null;
            foreach (string sec in field.Split('.'))
            {
                bod = Expression.MakeMemberAccess(par, par.Type.GetMember(sec)[0]);
                par = bod;
            }

            LambdaExpression lam = Expression.Lambda(bod, ent);
            this.InternalAddSort(lam, direction);
        }
    }
}

No hay comentarios:

Publicar un comentario