嵌套属性的通用类型排序

时间:2014-09-16 17:41:27

标签: c# asp.net .net

我有以下静态类:

public static class SortFilter
{
    public enum SortDirection { Ascending, Descending }

    public static IEnumerable<TEntity> Sort<TEntity, TKey>(IEnumerable<TEntity> entities, Func<TEntity, TKey> sorter, SortDirection d)
    {
        if (SortDirection.Ascending == d)
        {
            return entities.OrderBy(sorter);
        }
        else
        {
            return entities.OrderByDescending(sorter);
        }
    }

    public static IEnumerable<TEntity> Sort<TEntity>(IEnumerable<TEntity> entities, string sortParams)
    {
        string[] parameters = sortParams.Split('_');

        if (parameters.Count() == 1 || parameters.Count() > 2)
        {
            return entities;
        }
        else
        {
            if (parameters[1] == "ascending")
            {
                return Sort(entities, x => GetPropertyValue(x, parameters[0]), SortDirection.Ascending);
            }
            else if (parameters[1] == "descending")
            {
                return Sort(entities, x => GetPropertyValue(x, parameters[0]), SortDirection.Descending);
            }
            else
            {
                return entities;
            }
        }
    }

    public static object GetPropertyValue(object obj, string name)
    {

        return obj == null ? null : obj.GetType()
                                       .GetProperty(name)
                                       .GetValue(obj, null);
    }
}

我可以在List上调用Sort方法(User类具有Id和Name属性):

users = SortFilter.Sort(users, "Name_ascending");
users = SortFilter.Sort(users, "Id_ascending");

到目前为止,非常好:这样可以正常工作。

但是,让我们说我的User类也有一个UserGroup属性,我想按UserGroup的名称对我的用户列表进行排序。这个电话会明显失败:

users = SortFilter.Sort(users, "UserGroup.Name_ascending");

假设UserGroup.Name本身不是Type(因此GetPropertyValue方法将抛出异常)。

有没有办法制作一个足够通用的Sort函数,它将采用一个集合并通过作为参数发送的任意数量的嵌套属性对其进行排序?我有几个包含表数据的视图,应按用户单击的任何列(按升序或降序排序)进行排序。在控制器中对代码进行排序和过滤似乎很脏。

1 个答案:

答案 0 :(得分:0)

与LINQ的字符串参数一样使用DynamicLINQ

using System.Linq.Dynamic;
//..

if (parameters[1] == "ascending" || parameters[1] == "descending")
{  
    return entities.AsQueryable()
                   .OrderBy(string.Format("{0} {1}", parameters[0], parameters[1]))
}
else
{
    return entities;
}

可以在LinqSamples/DynamicQuery/Dynamic Expressions.html中找到文档here

当然支持嵌套属性。