我在页面上有一个网格,我希望可以在多个列上同时对其进行排序。
例如:
UserID FirstName LastName
=======================================
1 Bruce Wayne
2 Peter Parker
3 Clark Kent
4 Tony Stark
5 Helena Wayne
用户可以选择按LastName ASC排序,然后按FirstName DESC排序,这将生成以下内容:
UserID FirstName LastName
=======================================
3 Clark Kent
2 Peter Parker
4 Tony Stark
5 Helena Wayne
1 Bruce Wayne
用户可以重置订购并决定以其他方式订购。
如何在LINQ中实现这一目标?据我所知,链排序的方法是做类似
的事情superheroes.OrderBy(x => x.LastName).ThenByDescending(x => x.FirstName)
显然,我不想写出每个可能的列顺序组合(我的网格最多可能有10列)。有没有办法让订购序列动态化?
答案 0 :(得分:3)
IEnumerable的一种天真的方法(不完美或测试,但你明白了)。我把开关放在外面,所以比较只进行一次,而不是每次调用选择器。有点难看,因为你基本上不得不在OrderBy和ThenBy中重复自己。
enum OrderableColumns {UserID, FirstName, ...}
IOrderedEnumerable<SuperHero> OrderBy(SuperHeroes superheroes, OrderableColumns column)
{
switch(column)
{
case UserID:
return superheroes.OrderBy(x => x.UserID);
case FirstName:
return superheroes.OrderBy(x => x.FirstName);
...
}
}
IOrderedEnumerable<SuperHero> ThenBy(IOrderedEnumerable<SuperHero> superheroes, OrderableColumns column)
{
switch(column)
{
case UserID:
return superheroes.ThenBy(x => x.UserID);
case FirstName:
return superheroes.ThenBy(x => x.FirstName);
...
}
}
IOrderedEnumerable<SuperHero> OrderSuperheroes(SuperHeroes superheroes, params OrderableColumns[] columns)
{
var ordered = OrderBy(superheroes, columns[0]);
foreach(var col in columns.Skip(1))
ordered = ThenBy(ordered, col);
return ordered;
}
答案 1 :(得分:2)
答案 2 :(得分:0)
您可以构建Func<T,TResult>
动态,如下所示:
public static Func<T,object> GetExp<T>(string preportyName)
{
var instance = Expression.Parameter(typeof(T));
var callPreporty = Expression.PropertyOrField(instance, preportyName);
var lambda = Expression.Lambda<Func<T, object>>(callPreporty,instance);
return lambda.Compile();
}
像这样使用:
var pdotName = GetExp<Person>("Name"); //equals: p=>p.Name
var pdotID = GetExp<Person>("Id"); ////equals: p=>p.Id
var ordered = list.OrderBy(pdotName).ThenBy(pdotID);
//equals: list.OrderBy(p=>p.Name).ThenBy(p=>p.Id)