我有一个api Get
方法,它接受sort属性作为字符串。
在不使用switch
语句的情况下处理它的最佳解决方案是什么?
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());
}
我在微软的页面上找到了以下代码,但我相信应该有更优雅的方式来实现它。
答案 0 :(得分:2)
使用以下方法实现灵活排序。该方法需要属性名称和排序方向参数。
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();
}
用法:
IQueryable<Student> query = db.Set<Student>();
var orderBy = GetOrderByExpression<Student>(sortOrder, true);
if(orderBy != null){
query = orderBy(query);
}