Skip to content

Instantly share code, notes, and snippets.

@zaverden
Created June 20, 2017 10:40
Show Gist options
  • Save zaverden/c2d611f33f60cbe8234b420d87671c10 to your computer and use it in GitHub Desktop.
Save zaverden/c2d611f33f60cbe8234b420d87671c10 to your computer and use it in GitHub Desktop.
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace SomeProject
{
public static class IQueryableExtensions
{
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string ordering, bool desc = false)
{
return DynamicOrder(source, ordering, desc ? "OrderByDescending" : "OrderBy");
}
public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> source, string ordering)
{
return OrderBy(source, ordering, true);
}
public static IOrderedQueryable<T> ThenBy<T>(this IQueryable<T> source, string ordering, bool desc = false)
{
return DynamicOrder(source, ordering, desc ? "ThenByDescending" : "ThenBy");
}
public static IOrderedQueryable<T> ThenByDescending<T>(this IOrderedQueryable<T> source, string ordering)
{
return ThenBy(source, ordering, true);
}
private static IOrderedQueryable<T> DynamicOrder<T>(IQueryable<T> source, string ordering, string method)
{
var type = typeof(T);
var property = type.GetProperty(ordering, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
if (property == null)
{
throw new MissingMemberException(type.Name, ordering);
}
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
MethodCallExpression resultExp = Expression.Call(typeof(Queryable),
method,
new Type[] { type, property.PropertyType },
source.Expression, Expression.Quote(orderByExp));
return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(resultExp);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment