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


当前回答

首次安装动态 工具——> NuGet包管理器——>包管理器控制台

install-package System.Linq.Dynamic

使用System.Linq.Dynamic添加Namespace;

现在您可以使用OrderBy(“名称,年龄DESC”)

其他回答

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

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]);
    }
}

感谢Maarten(在LINQ中使用PropertyInfo对象查询一个集合),我得到了这个解决方案:

myList.OrderByDescending(x => myPropertyInfo.GetValue(x, null)).ToList();

在我的情况下,我在一个“ColumnHeaderMouseClick”(WindowsForm)上工作,所以只发现特定的列按下及其对应的PropertyInfo:

foreach (PropertyInfo column in (new Process()).GetType().GetProperties())
{
    if (column.Name == dgvProcessList.Columns[e.ColumnIndex].Name)
    {}
}

OR

PropertyInfo column = (new Process()).GetType().GetProperties().Where(x => x.Name == dgvProcessList.Columns[e.ColumnIndex].Name).First();

(确保你的列名称与对象属性匹配)

干杯

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

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);
}

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

这个答案是对@John Sheehan - Runscope提供的解决方案需要一个示例的评论的回应

请为我们其他人提供一个例子。

在DAL(数据访问层),

IEnumerable版本:

public  IEnumerable<Order> GetOrders()
{
    // i use Dapper to return IEnumerable<T> using Query<T>
    //.. do stuff

    return orders  // IEnumerable<Order>
}

IQueryable版本

public IQueryable<Order> GetOrdersAsQuerable()
{
    IEnumerable<Order> qry= GetOrders();

    // use the built-in extension method  AsQueryable in  System.Linq namespace
    return qry.AsQueryable();            
}

现在你可以使用IQueryable版本来绑定,例如Asp.net中的GridView和排序的好处(你不能使用IEnumerable版本进行排序)

我使用Dapper作为ORM并构建IQueryable版本,并在asp.net中的GridView中使用排序。

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安装