Use the following method to achieve flexible sorting. The method requires property name and sorting direction parameters.
public Func<IQueryable<T>, IOrderedQueryable<T>> GetOrderByExpression<T>(string propertyName, bool isDescending = false)
{
Type typeQueryable = typeof(IQueryable<T>);
ParameterExpression argQueryable = System.Linq.Expressions.Expression.Parameter(typeQueryable, "p");
var outerExpression = System.Linq.Expressions.Expression.Lambda(argQueryable, argQueryable);
var entityType = typeof(T);
ParameterExpression arg = System.Linq.Expressions.Expression.Parameter(entityType, "x");
Expression expression = arg;
PropertyInfo propertyInfo = entityType.GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
expression = System.Linq.Expressions.Expression.Property(expression, propertyInfo);
LambdaExpression lambda = System.Linq.Expressions.Expression.Lambda(expression, arg);
string methodName = isDescending ? "OrderByDescending" : "OrderBy";
MethodCallExpression resultExp = System.Linq.Expressions.Expression.Call(typeof(Queryable),
methodName,
new Type[] { typeof(T), entityType },
outerExpression.Body,
System.Linq.Expressions.Expression.Quote(lambda));
var finalLambda = System.Linq.Expressions.Expression.Lambda(resultExp, argQueryable);
return (Func<IQueryable<T>, IOrderedQueryable<T>>)finalLambda.Compile();
}
Usage:
IQueryable<Student> query = db.Set<Student>();
var orderBy = GetOrderByExpression<Student>(sortOrder, true);
if(orderBy != null){
query = orderBy(query);
}