Created
October 28, 2014 12:54
-
-
Save jrgcubano/a164d914032843024582 to your computer and use it in GitHub Desktop.
Order by helper with expressions and dot notation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#region Process Data (sort, group, filter, etc) | |
public static EnumerableQuery GroupBy(this IOrderedQueryable source, string property) | |
{ | |
return ApplyGroup(source, property, "GroupBy"); | |
} | |
public static IOrderedQueryable OrderBy(this IQueryable source, string property) | |
{ | |
return ApplyOrder(source, property, "OrderBy"); | |
} | |
public static IOrderedQueryable OrderByDescending(this IQueryable source, string property) | |
{ | |
return ApplyOrder(source, property, "OrderByDescending"); | |
} | |
public static IOrderedQueryable ThenBy(this IOrderedQueryable source, string property) | |
{ | |
return ApplyOrder(source, property, "ThenBy"); | |
} | |
public static IOrderedQueryable ThenByDescending(this IOrderedQueryable source, string property) | |
{ | |
return ApplyOrder(source, property, "ThenByDescending"); | |
} | |
static IOrderedQueryable ApplyOrder(IQueryable source, string property, string methodName) | |
{ | |
string[] props = property.Split('.'); | |
Type type = source.ElementType; | |
ParameterExpression arg = Expression.Parameter(type, "x"); | |
Expression expr = arg; | |
foreach (string prop in props) | |
{ | |
// reflection | |
PropertyInfo pi = type.GetProperty(prop); | |
expr = Expression.Property(expr, pi); | |
type = pi.PropertyType; | |
} | |
Type delegateType = typeof(Func<,>).MakeGenericType(source.ElementType, type); | |
LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg); | |
object result = typeof(Queryable).GetMethods().Single( | |
method => method.Name == methodName | |
&& method.IsGenericMethodDefinition | |
&& method.GetGenericArguments().Length == 2 | |
&& method.GetParameters().Length == 2) | |
.MakeGenericMethod(source.ElementType, type) | |
.Invoke(null, new object[] { source, lambda }); | |
return (IOrderedQueryable)result; | |
} | |
static EnumerableQuery ApplyGroup(IQueryable source, string property, string methodName) | |
{ | |
string[] props = property.Split('.'); | |
Type type = source.ElementType; | |
ParameterExpression arg = Expression.Parameter(type, "x"); | |
Expression expr = arg; | |
foreach (string prop in props) | |
{ | |
// reflection | |
PropertyInfo pi = type.GetProperty(prop); | |
expr = Expression.Property(expr, pi); | |
type = pi.PropertyType; | |
} | |
Type delegateType = typeof(Func<,>).MakeGenericType(source.ElementType, type); | |
LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg); | |
object result = typeof(Queryable).GetMethods().Single( | |
method => method.Name == methodName | |
&& method.IsGenericMethodDefinition | |
&& method.GetGenericArguments().Length == 2 | |
&& method.GetParameters().Length == 2) | |
.MakeGenericMethod(source.ElementType, type) | |
.Invoke(null, new object[] { source, lambda }); | |
return (EnumerableQuery)result; | |
} | |
#endregion |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment