-
-
Save neoGeneva/1878868 to your computer and use it in GitHub Desktop.
public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, string sortExpression) | |
{ | |
if (source == null) | |
throw new ArgumentNullException("source", "source is null."); | |
if (string.IsNullOrEmpty(sortExpression)) | |
throw new ArgumentException("sortExpression is null or empty.", "sortExpression"); | |
var parts = sortExpression.Split(' '); | |
var isDescending = false; | |
var propertyName = ""; | |
var tType = typeof(T); | |
if (parts.Length > 0 && parts[0] != "") | |
{ | |
propertyName = parts[0]; | |
if (parts.Length > 1) | |
{ | |
isDescending = parts[1].ToLower().Contains("esc"); | |
} | |
PropertyInfo prop = tType.GetProperty(propertyName); | |
if (prop == null) | |
{ | |
throw new ArgumentException(string.Format("No property '{0}' on type '{1}'", propertyName, tType.Name)); | |
} | |
var funcType = typeof(Func<,>) | |
.MakeGenericType(tType, prop.PropertyType); | |
var lambdaBuilder = typeof(Expression) | |
.GetMethods() | |
.First(x => x.Name == "Lambda" && x.ContainsGenericParameters && x.GetParameters().Length == 2) | |
.MakeGenericMethod(funcType); | |
var parameter = Expression.Parameter(tType); | |
var propExpress = Expression.Property(parameter, prop); | |
var sortLambda = lambdaBuilder | |
.Invoke(null, new object[] { propExpress, new ParameterExpression[] { parameter } }); | |
var sorter = typeof(Queryable) | |
.GetMethods() | |
.FirstOrDefault(x => x.Name == (isDescending ? "OrderByDescending" : "OrderBy") && x.GetParameters().Length == 2) | |
.MakeGenericMethod(new[] { tType, prop.PropertyType }); | |
return (IQueryable<T>)sorter | |
.Invoke(null, new object[] { source, sortLambda }); | |
} | |
return source; | |
} |
How to change this code to support sorting for multiple columns. Eg: a.OrderBy(x).ThenBy(y).ThenByDesc(z).
@BharateshChivate it wouldn't be too hard to create a "ThenBy" equivalent, the thing that would need to change is on line 47, finding the "ThenBy" or "ThenByDescending" instead of "OrderBy" and "OrderByDescending".
So personally I'm still using this in my code base, but I imagine there's nuget packages which do the same thing. I'm not sure but I think DynamicLinq by the ZZZ Projects folks would probably do the job, I've used a lot of their stuff in the past and definitely recommend them.
Thankyou for the reply.
Actually our sortExpression is in this format - id:asc,Name:desc.
Note: sortExpression can have multiple columns i.e., >2.
So, in this case I need to create my query like this - x.OrderBy(id).ThenByDesc(Name).
But the above code written by you works for only 1 column. I wanted to understand how to make this code work for multiple columna in sortexpression.
Thank you!
I'd like to add that this is a beautiful piece of heavy voodoo that helped me genericise server-side pagination.
Thank you!