Last active
February 29, 2016 05:11
-
-
Save worldspawn/c054ddcda0bcdf6b45fe to your computer and use it in GitHub Desktop.
Order a queryable based on a string input. "Members" can be a value like: "Name, Company.Type desc, Company.Name". Handles nested property references, ascending/descending and nullable/nonnullable targets.
This file contains 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
private IQueryable<T> Order<T>(IQueryable<T> list, string members) | |
{ | |
var param = Expression.Parameter(list.ElementType, "r"); | |
bool thenMode = false; | |
foreach (var member in members.Split(',')) | |
{ | |
MemberExpression memberExpression = null; | |
var chop = member.Split(' '); | |
foreach (var memberPart in chop[0].Split('.')) | |
{ | |
memberExpression = Expression.PropertyOrField((Expression)memberExpression ?? param, memberPart); | |
} | |
bool sortDescending = false; | |
if (chop.Length > 1) | |
{ | |
sortDescending = chop[1].IndexOf("desc", StringComparison.InvariantCultureIgnoreCase) > -1; | |
} | |
string command; | |
if (thenMode) | |
{ | |
command = sortDescending ? "ThenByDescending" : "ThenBy"; | |
} | |
else | |
{ | |
command = sortDescending ? "OrderByDescending" : "OrderBy"; | |
} | |
var exp = Expression.Lambda(memberExpression, param); | |
var resultExpression = Expression.Call(typeof(Queryable), command, new[] { typeof(T), memberExpression.Type }, list.Expression, Expression.Quote(exp)); | |
list = list.Provider.CreateQuery<T>(resultExpression); | |
thenMode = true; | |
} | |
return list; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment