2008-12-23 96 views
66

我有一个方法,它给出参数“bool sortAscending”。现在我想用LINQ根据这个参数创建排序列表。我当时是这样的:在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; 

正如你所看到的,这两个查询只有“升序”和“ “降”。我想合并两个查询,但我不知道如何。有没有人有答案?

+0

所以,你想有一个查询既可以做升序还是降序取决于bool sortAsvending值?那是对的吗。 – 2008-12-23 11:58:23

回答

100

您可以轻松的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); 
39

就实现方式而言,这将方法 - 从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到对象)是使用乘数-1/1。这只对数字数据非常有用,但却是达到相同结果的厚颜无耻的方式。

+0

我正要写这个完全一样的东西,然后我的VS冻结:( – 2008-12-23 12:00:53

+1

使用乘数也失败了int.MinValue的返回值。 – 2008-12-23 12:09:21

5

有关所需属性排序倒序什么,

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

然后做类似

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

它是Reverse()太慢吗?

0

除了通过@乔恩双向飞碟给出的美丽解决方案,我还需要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); 
    }