File: UI\WebControls\Expressions\OrderByExpression.cs
Project: ndp\fx\src\xsp\system\Extensions\System.Web.Extensions.csproj (System.Web.Extensions)
namespace System.Web.UI.WebControls.Expressions {    
    using System;
    using System.Collections.ObjectModel;
    using System.Diagnostics;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Web.Resources;
    using System.Web.UI;
 
    [
    PersistChildren(false),
    ParseChildren(true, "ThenByExpressions")
    ]
    public class OrderByExpression : DataSourceExpression {
        private const string OrderByMethod = "OrderBy";
        private const string ThenByMethod = "ThenBy";
        private const string OrderDescendingByMethod = "OrderByDescending";
        private const string ThenDescendingByMethod = "ThenByDescending";
 
        private Collection<ThenBy> _thenByExpressions;
 
        public string DataField {
            get {
                return (string)ViewState["DataField"] ?? String.Empty;
            }
            set {
                ViewState["DataField"] = value;
            }
        }
 
        public SortDirection Direction {
            get {
                object o = ViewState["Direction"];
                return o != null ? (SortDirection)o : SortDirection.Ascending;
            }
            set {
                ViewState["Direction"] = value;
            }
        }
 
        [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
        public Collection<ThenBy> ThenByExpressions {
            get {
                if (_thenByExpressions == null) {
                    // 
                    _thenByExpressions = new Collection<ThenBy>();
                }
                return _thenByExpressions;
            }
        }
 
        public override IQueryable GetQueryable(IQueryable source) {
            if (source == null) {
                return null;
            }
 
            if (String.IsNullOrEmpty(DataField)) {
                throw new InvalidOperationException(AtlasWeb.Expressions_DataFieldRequired);
            }
 
            ParameterExpression pe = Expression.Parameter(source.ElementType, String.Empty);
            source = CreateSortQueryable(source, pe, Direction, DataField, false /* isThenBy */);
 
            foreach (ThenBy thenBy in ThenByExpressions) {
                source = CreateSortQueryable(source, pe, thenBy.Direction, thenBy.DataField, true /* isThenBy */);
            }
 
            return source;
        }
 
        private static IQueryable CreateSortQueryable(IQueryable source, ParameterExpression parameterExpression, SortDirection direction, string dataField, bool isThenBy) {
            string methodName = isThenBy ? GetThenBySortMethod(direction) : GetSortMethod(direction);
            Expression propertyExpression = ExpressionHelper.CreatePropertyExpression(parameterExpression, dataField);
 
            return source.Call(methodName,
                               Expression.Lambda(propertyExpression, parameterExpression),
                               source.ElementType,
                               propertyExpression.Type);
        }
 
        private static string GetSortMethod(SortDirection direction) {
            switch (direction) {
                case SortDirection.Ascending:
                    return OrderByMethod;
                case SortDirection.Descending:
                    return OrderDescendingByMethod;
                default:
                    Debug.Fail("shouldn't get here!");
                    return OrderByMethod;
            }
        }
 
        private static string GetThenBySortMethod(SortDirection direction) {
            switch (direction) {
                case SortDirection.Ascending:
                    return ThenByMethod;
                case SortDirection.Descending:
                    return ThenDescendingByMethod;
                default:
                    Debug.Fail("shouldn't get here!");
                    return null;
            }
        }
    }
}