写一个针对IQueryable<T>的扩展方法支持动态排序
所谓的动态排序是指支持任意字段、任意升序降序的排序。我们希望在客户端按如下格式写:
localhost:8000/api/items?sort=title
localhost:8000/api/items?sort=name,title
localhost:8000/api/items?sort=-name,title
字段前面加-表示降序,否则是升序。
接下来要做的就是解析查询字符串中的字段,组成排序的表达式树作为OrderBy方法的实参。
首先安装如下:
install-package system.linq.dynamic
写一个针对IQueryable<T>,返回IQueryable<T>类型的扩展方法:
using System.Linq.Dynamic; public static class IQueryableExtensions { public static IQueryable<T> ApplySort<T>(this IQueryable<T> source, string sort) { if(source == null) { throw new ArgumentNullException("source"); } if(sort == null) { return source; } //把以逗号分隔的排序字符串放数组中 var listSort = sort.Split(','); string completeSortExpression = ""; foreach(var sortOption in listSort) { //如果排序字段以-开头就降序,否则升序 if(sortOption.StartsWith("-")) { completeSortExpression = sortOption.Remove(0, 1) + " descending,"; } else { completeSortExpression = completeSortExpression + sortOption + ","; } } if(!string.IsNullOrWhiteSpace(completeSortExpression)) { source = source.OrderBy(completeSortExpression .Remove(completeSortExpression.Count()-1)); } return sort; } }
在controller下的action中,大致这样使用:
public IHttpActionResult Get(string sort="id") { try { var items = _repo.GetItems(); var result = items .ApplySort(sort) .ToList() .Select(e => ItemFactory.ConvertToViewModel(e)); return OK(result); } catch(Exception) { //TODO:处理异常 } }