【问题标题】:Generic type sorting by nested properties按嵌套属性进行泛型类型排序
【发布时间】:2014-09-16 17:41:26
【问题描述】:

我有以下静态类:

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 函数,该函数将接受一个集合并通过作为参数发送的任意数量的嵌套属性对其进行排序?我有几个表数据视图,应按用户单击的任何列按升序或降序排序。在控制器中对代码进行排序和过滤似乎很脏。

【问题讨论】:

  • 你为什么不使用 Linq 排序方法?你可以只做users = users.Sort(u =&gt; u.UserGroup.Name).ToList(); 而不是用你的SortFilter 类重新发明(分类)轮子。
  • 主要是因为我希望能够随时为任何集合调用该方法,而不仅仅是用户。假设我在应用程序中还有一个 Player 和 Team 类。我想实现这个:players = players.OrderBy(p =&gt; p.Name); 以及这个players = players.OrderByDescending(p =&gt; p.Team.Name) 使用相同的排序方法。
  • 那为什么不起作用? Linq 排序方法解析您插入的任何属性或表达式。如果你愿意,你可以做players = players.OrderBy(p =&gt; p.Parent.Team.Staff[0].Name.FirstName);,或者例如,人们经常通过players = players.OrderBy(p =&gt; Guid.NewGuid().ToString());得到随机排序,这也有效。所以,坚持我最初的问题,为什么你不能在你的特定实例中使用 Linq?

标签: c# asp.net .net


【解决方案1】:

对于 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;
}

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

当然支持嵌套属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    • 2016-03-01
    • 1970-01-01
    • 2015-10-20
    • 2018-07-03
    相关资源
    最近更新 更多