14

エンドユーザーが返されたレポートの並べ替え順序で複数のフィールドを選択できるレポートインターフェイスがあります。私が抱えている問題は、ソートフィールドのリストを反復処理しているため、OrderBy/ThenByメソッドを実際にチェーンできないことです。私はこのようなことを考えています:

foreach (string sort in data.SortParams)
{
    switch (sort)
    {
        case "state":
            query = query.ThenBy(l => l.RegionCode);
            break;
        case "type":
            query = query.ThenBy(l => l.Type);
            break;
        case "color":
            query = query.ThenBy(l => l.Color);
            break;
        case "category":
            query = query.OrderBy(l => l.Category);
            break;
    }
}

(注:わかりやすくするために、これが最初の並べ替えアイテムであるかどうかを判断するスイッチを削除しました。)

コレクションを反復処理して並べ替え順序を決定する方法について何か考えはありますか?

4

3 に答える 3

23

最初の「シード」OrderByを使用すると、やりたいことができます。

句を添付する前に、最初に(または)OrderByを作成するために呼び出す必要がある編集:IOrderedEnumerableIOrderedQueryableThenBy

var orderedQuery = query.OrderBy(l => 0);
foreach (string sort in data.SortParams)
{
    switch (sort)
    {
        case "state":
            orderedQuery = orderedQuery.ThenBy(l => l.RegionCode);
            break;
        case "type":
            orderedQuery = orderedQuery.ThenBy(l => l.Type);
            break;
        case "color":
            orderedQuery = orderedQuery.ThenBy(l => l.Color);
            break;
        case "category":
            orderedQuery = orderedQuery.ThenBy(l => l.Category);
            break;
    }
}
query = orderedQuery;  // cast back to original type.

より柔軟なものが必要な場合は、この回答を確認してください

于 2012-11-21T16:20:51.400 に答える
14

質問で述べたのと同じ問題に取り組むために、これらの拡張メソッドを作成しました。

public static class QueryableExtensions
{
    public static IOrderedQueryable<T> AppendOrderBy<T, TKey>(this IQueryable<T> query, Expression<Func<T, TKey>> keySelector)
        => query.Expression.Type == typeof(IOrderedQueryable<T>)
        ? ((IOrderedQueryable<T>) query).ThenBy(keySelector)
        : query.OrderBy(keySelector);

    public static IOrderedQueryable<T> AppendOrderByDescending<T, TKey>(this IQueryable<T> query, Expression<Func<T, TKey>> keySelector)
        => query.Expression.Type == typeof(IOrderedQueryable<T>)
            ? ((IOrderedQueryable<T>)query).ThenByDescending(keySelector)
            : query.OrderByDescending(keySelector);
}

問題のコードは、次のようにリファクタリングできます。

foreach (string sort in data.SortParams)
{
    switch (sort)
    {
        case "state":
            query = query.AppendOrderBy(l => l.RegionCode);
            break;
        case "type":
            query = query.AppendOrderBy(l => l.Type);
            break;
        case "color":
            query = query.AppendOrderBy(l => l.Color);
            break;
        case "category":
            query = query.AppendOrderBy(l => l.Category);
            break;
    }
}

備考これらの拡張メソッドは、式ツリー内の前の式のみをチェックして、使用するかどうかを決定しますOrderByThenByその間に他の式を使用することはできません。これにも取り組みたい場合は、ツリー全体をウォークスルーする必要があります。これにより、不要なオーバーヘッドが追加される可能性があります:)

于 2017-08-03T13:42:10.940 に答える
-1

オールインワンのLinqクエリを使用することは、読みやすさの観点からは最善のオプションではない可能性があります。IQueryableを使用して、メモリ内にクエリを作成します。同様の種類のswitchステートメント(ただしIQueryableを使用)を使用し、最後に.ToListを実行(つまり列挙)して、サーバーで目的のクエリを実行します。

于 2012-11-21T16:10:48.220 に答える