我想在多个属性上对列表进行排序。我知道我可以使用
List<Order> l = source.OrderBy(c=> c.Property1).ThenBy(c=> c.Property2).ToList();
但是,它仅用于提升。如果我想对列表进行降序排序,我需要另一个代码
List<Order> l = source.OrderByDescending(c=> c.Property1).ThenByDescending(c=> c.Property2).ToList();
如果我想将property1排序为升序而将property2排序为降序,我必须使用
List<Order> l = source.OrderBy(c=> c.Property1).ThenByDescending(c=> c.Property2).ToList();
对于2个属性的排序,我需要4个不同的代码,在3个属性上,我需要9个不同的代码。没有好处。我想知道是否有办法在一个代码中进行排序。谢谢。
答案 0 :(得分:1)
您可以编写自己的LINQ扩展来确定要选择的方法。例如:
public static class LinqExtensions
{
public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>(this IQueryable<TSource> source, Expression<Func<TSource, TKey>> keySelector, bool ascending)
{
return ascending ? source.OrderBy(keySelector) : source.OrderByDescending(keySelector);
}
}
然后你可以像这样使用它:
source.OrderBy(a => a.Id, ascending);
答案 1 :(得分:1)
正如我在评论中提到的,你可以创建这样的东西......
public static class LinqExtension
{
public static IOrderedEnumerable<TSource> OrderByAsc<TSource, TKey>(
this IEnumerable<TSource> source,
Expression<Func<T, object>> expression)
{
IEnumerable<TSource> newEnumerable = source;
int ctr = 0;
NewArrayExpression array = expression.Body as NewArrayExpression;
foreach( object obj in ( IEnumerable<object> )( array.Expressions ) )
{
if(ctr == 0)
newEnumerable = newEnumerable
.OrderBy(item => item.GetType().GetProperty(obj.ToString()).GetValue(item, null));
else
newEnumerable = newEnumerable
.ThenBy(item => item.GetType().GetProperty(obj.ToString()).GetValue(item, null));
ctr++;
}
return newEnumerable;
}
public static IOrderedEnumerable<TSource> OrderByDesc<TSource, TKey>(
this IEnumerable<TSource> source,
Expression<Func<T, object>> expression)
{
IEnumerable<TSource> newEnumerable = source;
NewArrayExpression array = expression.Body as NewArrayExpression;
int ctr = 0;
foreach( object obj in ( IEnumerable<object> )( array.Expressions ) )
{
if(ctr == 0)
newEnumerable = newEnumerable
.OrderByDescending(item => item.GetType().GetProperty(obj.ToString()).GetValue(item, null));
else
newEnumerable = newEnumerable
.ThenByDescending(item => item.GetType().GetProperty(obj.ToString()).GetValue(item, null));
ctr++;
}
return newEnumerable;
}
}
并像这样使用它:
using myNameSpace.LinqExtensions;
...
l = l.OrderByAsc(item => new [] { item.Prop1, item.Prop2, item.Prop3});
l = l.OrderByDesc(item => new [] { item.Prop1, item.Prop2, item.Prop3});
当然,您可以尝试创建一个扩展,通过升序和降序将两个顺序组合成一个方法。只是一个想法。
免责声明:我在记事本上写了这封信,由于资源不足,我们没有对其进行过测试。
答案 2 :(得分:0)
System.Linq.Dynamic包提供了一个OrderBy扩展方法,它只接受一个字符串:
using System.Linq.Dynamic;
//...
var l = source.OrderBy("Property1 ascending, Property2 descending").ToList();
您可以使用它来动态构建精美的表达式:
string orderByClause = string.Format("Property1 {0}, Property2 {1}", "ascending", "descending");
var l = source.OrderBy(orderByClause).ToList();
有关项目Wiki
中的更多信息,请参阅IQueryable Extension Methods