在LINQ中升序/降序 - 可以通过参数更改顺序吗?

时间:2008-12-23 11:52:59

标签: c# linq

我有一个给出参数“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;

正如您所看到的,两个查询的区别仅在于“升序”。 “降”。我想合并两个查询,但我不知道如何。有人有答案吗?

4 个答案:

答案 0 :(得分:109)

您可以在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);

答案 1 :(得分:41)

就如何实现这一点而言,这会将方法从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的乘数。这仅对数字数据非常有用,但却是实现相同结果的一种厚颜无耻的方式。

答案 2 :(得分:6)

如何通过所需的属性对desc进行排序,

   blah = blah.OrderByDescending(x => x.Property);

然后做类似

的事情
  if (!descending)
  {
       blah = blah.Reverse()
  }
  else
  {
      // Already sorted desc ;)
  }

反向()太慢了吗?

答案 3 :(得分:0)

除了@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);
    }