Linq to Objects按任意数量的参数排序

时间:2011-09-06 16:14:16

标签: c# linq dynamic sql-order-by func

我有一个定义排序的Func列表:

var ordering = new List<Func<Person, IComparable>> 
                 { x => x.Surname, x => x.FirstName };

我可以用......之类的东西订购结果。

people = people.OrderBy(ordering[0]).ThenBy(ordering[1]);

我正在尝试在列表可以包含任意数量的连续排序时如何执行上述操作。有可能吗?

5 个答案:

答案 0 :(得分:6)

people = people.OrderBy(ordering[0]).ThenBy(ordering[1]).ThenBy(ordering[2]);

相同
var orderedPeople = people.OrderBy(ordering[0]);
orderedPeople = orderedPeople.ThenBy(ordering[1]);
orderedPeople = orderedPeople.ThenBy(ordering[2]);
people = orderedPeople;

所以你只需编写一个这样的循环:

if (ordering.Count != 0)
{
    var orderedPeople = people.OrderBy(ordering[0]);
    for (int i = 1; i < ordering.Count; i++)
    {
        orderedPeople = orderedPeople.ThenBy(ordering[i]);
    }
    people = orderedPeople;
}

答案 1 :(得分:4)

正如其他人所提到的,你可以使用循环来做到这一点。

如果您愿意,还可以使用Aggregate运算符:

// Requires a non-empty ordering sequence.
var result2 = ordering.Skip(1)
                      .Aggregate(people.OrderBy(ordering.First()), Enumerable.ThenBy); 

(或)

// Shorter and more "symmetric" but potentially more inefficient.
// x => true should work because OrderBy is a stable sort.
var result = ordering.Aggregate(people.OrderBy(x => true), Enumerable.ThenBy);

答案 2 :(得分:3)

你应该可以做类似的事情

people = people.OrderBy(ordering[0])
foreach(var order in ordering.Skip(1))
{
  people = people.ThenBy(order);
}

另外

 for(i = 0; i < ordering.Count; i++)
 {
    people = i == 0 ? people.OrderBy(ordering[i]) : people.ThenBy(ordering[i]);
 }

答案 3 :(得分:2)

请记住LINQ执行是延迟的。您可以在访问结果之前按顺序构建表达式,执行以下操作:

var ordered = unordered.OrderBy(ordering.First());
foreach (var orderingItem in ordering.Skip(1))
{
    ordered = ordered.ThenBy(orderingItem);
}

答案 4 :(得分:0)

您可能希望通过动态构建表达式来实现此目的。更多信息:Dynamic LINQ and Dynamic Lambda expressions?