ascending/descending in LINQ - can one change the order via parameter?

后端 未结 4 878
时光取名叫无心
时光取名叫无心 2020-11-28 04:45

I have a method which is given the parameter \"bool sortAscending\". Now I want to use LINQ to create sorted list depending on this parameter. I got then this:



        
相关标签:
4条回答
  • 2020-11-28 04:50

    What about ordering desc by the desired property,

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

    And then doing something like

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

    Is it Reverse() too slow?

    0 讨论(0)
  • 2020-11-28 04:57

    In terms of how this is implemented, this changes the method - from OrderBy/ThenBy to OrderByDescending/ThenByDescending. However, you can apply the sort separately to the main query...

    var qry = from .... // or just dataList.AsEnumerable()/AsQueryable()
    
    if(sortAscending) {
        qry = qry.OrderBy(x=>x.Property);
    } else {
        qry = qry.OrderByDescending(x=>x.Property);
    }
    

    Any use? You can create the entire "order" dynamically, but it is more involved...

    Another trick (mainly appropriate to LINQ-to-Objects) is to use a multiplier, of -1/1. This is only really useful for numeric data, but is a cheeky way of achieving the same outcome.

    0 讨论(0)
  • 2020-11-28 05:03

    You can easily create your own extension method on IEnumerable or 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);
    }
    

    Yes, you lose the ability to use a query expression here - but frankly I don't think you're actually benefiting from a query expression anyway in this case. Query expressions are great for complex things, but if you're only doing a single operation it's simpler to just put that one operation:

    var query = dataList.OrderByWithDirection(x => x.Property, direction);
    
    0 讨论(0)
  • 2020-11-28 05:04

    In addition to the beautiful solution given by @Jon Skeet, I also needed ThenBy and ThenByDescending, so I am adding it based on his solution:

        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);
        }
    
    0 讨论(0)
提交回复
热议问题