我在VS2008动态LINQ示例中找到了一个示例,允许您使用类似sql的字符串(例如OrderBy(“Name, Age DESC”))进行排序。不幸的是,所包含的方法只适用于IQueryable<T>。有什么办法得到这个功能IEnumerable<T>?


当前回答

Too easy而不复杂:

使用System.Linq.Dynamic添加;在顶端。 使用vehicles = vehicles. asqueryable()。OrderBy("Make ASC, Year DESC").ToList();

编辑:为了节省时间,将System.Linq. dynamic . core (System.Linq. core)修改为Dynamic已弃用)程序集不是框架的一部分,但可以从nuget: System.Linq.Dynamic.Core安装

其他回答

你可以这样做,对多个顺序

IOrderedEnumerable<JToken> sort;

if (query.OrderBys[0].IsDESC)
{
    sort = jarry.OrderByDescending(r => (string)r[query.OrderBys[0].Key]);
}
else
{
    sort = jarry.OrderBy(r =>
        (string) r[query.OrderBys[0].Key]); 
}

foreach (var item in query.OrderBys.Skip(1))
{
    if (item.IsDESC)
    {
        sort = sort.ThenByDescending(r => (string)r[item.Key]);
    }
    else
    {
        sort = sort.ThenBy(r => (string)r[item.Key]);
    }
}
var result1 = lst.OrderBy(a=>a.Name);// for ascending order. 
 var result1 = lst.OrderByDescending(a=>a.Name);// for desc order. 

我想使用反射来获得你想要排序的任何属性是可行的:

IEnumerable<T> myEnumerables
var query=from enumerable in myenumerables
          where some criteria
          orderby GetPropertyValue(enumerable,"SomeProperty")
          select enumerable

private static object GetPropertyValue(object obj, string property)
{
    System.Reflection.PropertyInfo propertyInfo=obj.GetType().GetProperty(property);
    return propertyInfo.GetValue(obj, null);
}

注意,使用反射比直接访问属性要慢得多,因此必须研究性能。

我试图这样做,但有问题与Kjetil Watnedal的解决方案,因为我不使用内联linq语法-我更喜欢方法风格的语法。我的具体问题是尝试使用自定义IComparer进行动态排序。

我的解决方案是这样的:

给定一个IQueryable查询,如下:

List<DATA__Security__Team> teams = TeamManager.GetTeams();
var query = teams.Where(team => team.ID < 10).AsQueryable();

给定一个运行时排序字段参数:

string SortField; // Set at run-time to "Name"

动态OrderBy看起来是这样的:

query = query.OrderBy(item => item.GetReflectedPropertyValue(SortField));

这是使用一个叫做GetReflectedPropertyValue()的小助手方法:

public static string GetReflectedPropertyValue(this object subject, string field)
{
    object reflectedValue = subject.GetType().GetProperty(field).GetValue(subject, null);
    return reflectedValue != null ? reflectedValue.ToString() : "";
}

最后一件事——我提到过我想让OrderBy使用自定义iccomparer——因为我想做自然排序。

要做到这一点,我只需要改变OrderBy为:

query = query.OrderBy(item => item.GetReflectedPropertyValue(SortField), new NaturalSortComparer<string>());

有关NaturalSortComparer()的代码,请参阅这篇文章。

你可以用这个:

        public List<Book> Books(string orderField, bool desc, int skip, int take)
{
    var propertyInfo = typeof(Book).GetProperty(orderField);

    return _context.Books
        .Where(...)
        .OrderBy(p => !desc ? propertyInfo.GetValue(p, null) : 0)
        .ThenByDescending(p => desc ? propertyInfo.GetValue(p, null) : 0)
        .Skip(skip)
        .Take(take)
        .ToList();
}