写一个针对IQueryable的扩展方法支持动态排序

 

所谓的动态排序是指支持任意字段、任意升序降序的排序。我们希望在客户端按如下格式写:

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:处理异常
    }
}

 

你可能感兴趣的:(写一个针对IQueryable的扩展方法支持动态排序)