2012-03-20 68 views
20

我目前订购使用IQueryable的排序依据的方法如下自定义对象的列表的IQueryable顺序:由两个或多个属性

mylist.AsQueryable().OrderBy("PropertyName"); 

现在,我希望通过多个属性进行排序。有没有办法做到这一点?

感谢, 雅尼斯

回答

38
OrderBy(i => i.PropertyName).ThenBy(i => i.AnotherProperty) 

在OrderBy和ThenBy中,您必须提供keySelector函数,该函数从对象中选择用于排序的键。所以,如果你只知道在运行时的属性名,那么你可以做这样的功能有类似的反思:

var propertyInfo = i.GetType().GetProperty("PropertyName"); 
var sortedList = myList.OrderBy(i => propertyInfo.GetValue(i, null)) 

但它会比较慢,然后直接访问属性。你也可以使用Linq.Expressions随时“编译”这样的函数,它的运行速度比反射速度快,但它不是很容易。或者你可以在WPF中使用CollectionViewSource及其排序功能。

并且不要忘记OrderBy()返回排序的枚举,并且它不会对inset中已存在的List进行排序。在你的例子中,你没有将排序列表保存到变量中。

+0

尽管如此。 PropertyName实际上是一个String(导致它从一个排序选择器中进来)。所以我不能使用这个。任何替代品? – Yannis 2012-03-21 08:14:55

+0

在OrderBy和ThenBy中,您必须提供keySelector函数,该函数从对象中选择用于排序的键。使用字符串属性名称可以使用反射来创建此类函数:var propertyInfo = i.GetType()。GetProperty(“PropertyName”); myList.OrderBy(i => propertyInfo.GetValue(i,null))''但它会变慢,然后直接访问属性。你也可以用Expressiosn动态地“编译”这样的功能,并且它的运行速度比表达式要快,但它不是很容易。或者你可以在WPF中使用CollectionViewSource及其排序功能 – Nikolay 2012-03-21 08:52:36

+0

@Nikolay - 为什么不使用动态Linq呢? – 2012-03-21 10:37:32

10

你可以使用.ThenBy

var result = mylist 
    .AsQueryable() 
    .OrderBy(x => x.PropertyName) 
    .ThenBy(x => x.SomeOtherProperty); 
+0

这就是事情。 PropertyName实际上是一个String(导致它从一个排序选择器中进来)。所以我不能使用这个。任何替代品? – Yannis 2012-03-20 17:02:51

5

你可能想使用ThenBy扩展方法能够通过多个字段进行排序

return myList.AsQueryable().OrderBy(m=>m.Property1).ThenBy(m => m.Property2); 

如果您想要动态的Linq,看看LinqKit。我最近从here实施了Microsoft的动态Linq库,并能够使用字符串对两个字段进行排序。

太棒了!不知道这是否会在.NET 5中。

+0

尽管如此。 PropertyName实际上是一个String(导致它从一个排序选择器中进来)。所以我不能使用这个。任何替代品? – Yannis 2012-03-21 08:20:26

+0

@Yannis - 使用动态Linq – 2012-03-21 09:36:08