寫一個針對IQueryable<T>的擴充套件方法支援動態排序

Darren Ji發表於2016-01-21

 

所謂的動態排序是指支援任意欄位、任意升序降序的排序。我們希望在客戶端按如下格式寫:

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:處理異常
    }
}

 

相關文章