我如何根据用户输入在LINQ中使用OrderBy和ThenBy?
我在页面上有一个网格,我希望可以同时在多个列上进行排序。
例如:
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列)。 有没有办法使订购序列动态化?
您需要使用动态LINQ。 看一下Dynamic LINQ(第1部分:使用LINQ动态查询库)
IEnumerable的一种天真的方法(不完美或测试,但你明白了)。 我把开关放在外面,所以比较只进行一次,而不是每次调用选择器。 有点难看,因为你基本上不得不在OrderBy和ThenBy中重复自己。
enum OrderableColumns {UserID, FirstName, ...} IOrderedEnumerable OrderBy(SuperHeroes superheroes, OrderableColumns column) { switch(column) { case UserID: return superheroes.OrderBy(x => x.UserID); case FirstName: return superheroes.OrderBy(x => x.FirstName); ... } } IOrderedEnumerable ThenBy(IOrderedEnumerable superheroes, OrderableColumns column) { switch(column) { case UserID: return superheroes.ThenBy(x => x.UserID); case FirstName: return superheroes.ThenBy(x => x.FirstName); ... } } IOrderedEnumerable 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; }
您可以构建一个Func
Dynamic,如下所示:
public static Func GetExp(string preportyName) { var instance = Expression.Parameter(typeof(T)); var callPreporty = Expression.PropertyOrField(instance, preportyName); var lambda = Expression.Lambda>(callPreporty,instance); return lambda.Compile(); }
使用这样:
var pdotName = GetExp("Name"); //equals: p=>p.Name var pdotID = GetExp ("Id"); ////equals: p=>p.Id var ordered = list.OrderBy(pdotName).ThenBy(pdotID); //equals: list.OrderBy(p=>p.Name).ThenBy(p=>p.Id)