1

複数の列で同時に並べ替えることができるグリッドがページにあります。

例えば:

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個の列がある場合があります)。順序付けシーケンスを動的にする方法はありますか?

4

3 に答える 3

3

IEnumerable に対する素朴なアプローチです (完璧でもテスト済みでもありませんが、理解できます)。セレクターが呼び出されるたびにではなく、1 回だけ比較が行われるように、スイッチを外側に配置しました。ただし、本質的に 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;
}
于 2012-08-27T06:30:58.193 に答える
2

動的LINQを使用する必要があります。動的LINQをご覧ください(パート1:LINQ動的クエリライブラリの使用)

于 2012-08-27T06:20:32.200 に答える
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)
于 2012-08-27T07:04:41.313 に答える