private static IQueryable <T> ApplyOrderBy <T>(IQueryable <T> collection, OrderByInfo orderByInfo) { Type type = typeof(T); ParameterExpression arg = Expression.Parameter(type, "x"); Expression expr = arg; string prop = orderByInfo.PropertyName; // use reflection (not ComponentModel) to mirror LINQ PropertyInfo pi = OrmHelper.GetPropertyInfo <T>(prop); expr = Expression.Property(expr, pi); type = pi.PropertyType; Type delegateType = typeof(Func <,>).MakeGenericType(typeof(T), type); LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg); string methodName = String.Empty; if (!orderByInfo.Initial && collection is IOrderedQueryable <T> ) { methodName = orderByInfo.Direction == SortDirection.Ascending ? "ThenBy" : "ThenByDescending"; } else { methodName = orderByInfo.Direction == SortDirection.Ascending ? "OrderBy" : "OrderByDescending"; } //TODO: apply caching to the generic methodsinfos? return((IOrderedQueryable <T>) typeof(Queryable).GetMethods().Single( method => method.Name == methodName && method.IsGenericMethodDefinition && method.GetGenericArguments().Length == 2 && method.GetParameters().Length == 2) .MakeGenericMethod(typeof(T), type) .Invoke(null, new object[] { collection, lambda })); }