I have an api Get method which accepts sort property as a string.
What is a best solution to handle it without using switch statement?
public ActionResult Index(string sortOrder)
{
var students = from s in db.Students
select s;
switch (sortOrder)
{
case "LastName":
students = students.OrderByDescending(s => s.LastName);
break;
case "EnrollmentDate":
students = students.OrderBy(s => s.EnrollmentDate);
break;
case "Birthday":
students = students.OrderBy(s => s.Birthday);
break;
default:
students = students.OrderBy(s => s.LastName);
break;
}
return View(students.ToList());
}
Following code I found on microsoft's page, but I believe there is should be more elegant way to do it.
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With