LINQ 中的升序/降序 - 可以通过参数更改顺序吗?
Posted
技术标签:
【中文标题】LINQ 中的升序/降序 - 可以通过参数更改顺序吗?【英文标题】:ascending/descending in LINQ - can one change the order via parameter? 【发布时间】:2008-12-23 11:52:58 【问题描述】:我有一个方法,它的参数是“bool sortAscending”。现在我想使用 LINQ 根据这个参数创建排序列表。然后我得到了这个:
var ascendingQuery = from data in dataList
orderby data.Property ascending
select data;
var descendingQuery = from data in dataList
orderby data.Property descending
select data;
如您所见,这两个查询仅在“升序”方面有所不同。 “下降”。我想合并这两个查询,但我不知道如何。有人知道答案吗?
【问题讨论】:
所以您希望有一个查询可以根据 bool sortAsvending 值进行升序或降序操作?对吗? 【参考方案1】:您可以轻松地在 IEnumerable 或 IQueryable 上创建自己的扩展方法:
public static IOrderedEnumerable<TSource> OrderByWithDirection<TSource,TKey>
(this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
bool descending)
return descending ? source.OrderByDescending(keySelector)
: source.OrderBy(keySelector);
public static IOrderedQueryable<TSource> OrderByWithDirection<TSource,TKey>
(this IQueryable<TSource> source,
Expression<Func<TSource, TKey>> keySelector,
bool descending)
return descending ? source.OrderByDescending(keySelector)
: source.OrderBy(keySelector);
是的,您在这里失去了使用查询表达式的能力 - 但坦率地说,在这种情况下,我认为您实际上并没有从查询表达式中受益。查询表达式非常适合复杂的事情,但如果你只做一个操作,那么只做一个操作会更简单:
var query = dataList.OrderByWithDirection(x => x.Property, direction);
【讨论】:
感谢 Marc 纠正我的愚蠢 :) (这就是在午餐前发帖的问题......) 此帖由 SO.com 的两位名人回答和编辑 OrderByWithDirections 之一不应该返回升序吗? @KOL:我不确定你的意思。如果您将false
传递给descending
,它们都会升序返回。
@JonSkeet,感谢您的解决方案,但我已经发布了一个关于其使用的问题。见:***.com/questions/18348767/…【参考方案2】:
就如何实现而言,这改变了方法 - 从 OrderBy/ThenBy 到 OrderByDescending/ThenByDescending。但是,您可以将排序单独应用于主查询...
var qry = from .... // or just dataList.AsEnumerable()/AsQueryable()
if(sortAscending)
qry = qry.OrderBy(x=>x.Property);
else
qry = qry.OrderByDescending(x=>x.Property);
有用吗?您可以动态创建整个“订单”,但涉及更多...
另一个技巧(主要适用于 LINQ-to-Objects)是使用 -1/1 的乘数。这仅对数字数据真正有用,但这是实现相同结果的一种厚颜无耻的方式。
【讨论】:
我正要写这个完全相同的东西然后我的 VS 冻结了:( 对于 int.MinValue 的返回值,使用乘数也会失败。 为什么在 linq-query 中使用 orderBy 方法而不是 orderby 关键字? @Joshit 因为我需要在这两种情况下执行不同的操作,并且在这里使用 LINQ 查询语法与仅使用扩展方法相比没有任何好处。如果您更喜欢查询语法:去做,就可以了。 @MarcGravell 非常感谢您的快速回复!我想,如果两个性能编程的杰出人物这样做,那么值得一问是否有更深层次的原因;)【参考方案3】:按所需属性排序 desc 怎么样,
blah = blah.OrderByDescending(x => x.Property);
然后做类似的事情
if (!descending)
blah = blah.Reverse()
else
// Already sorted desc ;)
Reverse() 是不是太慢了?
【讨论】:
可能不是最优化的,但肯定是一个非常聪明的方法 @DiegoPenha 嗯,但万一它在物化数据之前对实体的 linq 应该是相同的,不是吗?我的意思是会相应地生成一个 sql 查询。你同意吗? @DiegoPenha 算了,linq to entity 不支持 .Reverse() 函数?【参考方案4】:除了@Jon Skeet 给出的漂亮解决方案,我还需要 ThenBy 和 ThenByDescending,所以我根据他的解决方案添加它:
public static IOrderedEnumerable<TSource> ThenByWithDirection<TSource, TKey>(
this IOrderedEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
bool descending)
return descending ?
source.ThenByDescending(keySelector) :
source.ThenBy(keySelector);
【讨论】:
以上是关于LINQ 中的升序/降序 - 可以通过参数更改顺序吗?的主要内容,如果未能解决你的问题,请参考以下文章
Linq 对string[]字符串数组进行排序 (升序降序乱序)