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

其他回答

你可以像这样定义一个从string到Func<>的字典:

Dictionary<string, Func<Item, object>> SortParameters = new Dictionary<string, Func<Item, object>>()
{
    {"Rank", x => x.Rank}
};

像这样使用它:

yourList.OrderBy(SortParameters["Rank"]);

在这种情况下,您可以根据字符串动态排序。

你可以将IEnumerable转换为IQueryable。

items = items.AsQueryable().OrderBy("Name ASC");

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

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

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

我还发现了一些有趣的东西。 如果你的数据源是一个数据表,你可以使用动态排序而不使用动态Linq

DataTable orders = dataSet.Tables["SalesOrderHeader"];
EnumerableRowCollection<DataRow> query = from order in orders.AsEnumerable()
                                         orderby order.Field<DateTime>("OrderDate")
                                         select order;
DataView view = query.AsDataView();
bindingSource1.DataSource = view;

参考:http://msdn.microsoft.com/en-us/library/bb669083.aspx(使用DataSetExtensions)

下面是另一种将其转换为DataView的方法:

DataTable contacts = dataSet.Tables["Contact"];    
DataView view = contacts.AsDataView();    
view.Sort = "LastName desc, FirstName asc";    
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();

你可以用这个:

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