4

重複の可能性:
動的 LINQ OrderBy

クライアント側のグリッド コントロール (KendoUI グリッド) からサーバーに渡されるカスタム ソート オプションのリストがあります。これらの並べ替えオプションには、文字列として並べ替えるプロパティがあります。sort オブジェクトの値をチェックし、適切な LINQ を適用する switch メソッドを作成しました。

    private IQueryable<Report> SortReports(IQueryable<Report> reports, KendoSort sort)
    {
        switch (sort.Field)
        {
            case "name":
                return sort.Dir == "asc" ? reports.OrderBy(x => x.Name) : reports.OrderByDescending(x => x.Name);
            case "description":
                return sort.Dir == "asc" ? reports.OrderBy(x => x.Description) : reports.OrderByDescending(x => x.Description);
            default:
                return sort.Dir == "asc" ? reports.OrderBy(x => x.Id) : reports.OrderByDescending(x => x.Id);
        }
    }

これはうまく機能していますが、とても醜いようです。これを行いたいエンティティのすべてのタイプに対してカスタム関数を作成する必要がないように、リフレクションでこれを行うにはどうすればよいですか? エンティティに関係なく、これを実行する単一の関数があればいいのにと思います。

4

4 に答える 4

2

Dynamic LINQ を使用できます。これblog postについては、スコット・グーからです。

于 2012-10-22T05:47:36.823 に答える
1

リフレクションを使用します。ここで、KendoSort.Property は、並べ替えに必要な値を返す Report プロパティの PropertyInfo です。

private IQueryable<Report> SortReports(IQueryable<Report> reports, KendoSort sort)
{
    return sort.Dir == "asc" ? reports.OrderBy(x => sort.Property.GetValue(x)) : reports.OrderByDescending(x => sort.Property.GetValue(x));
}

しかし、反射は比較的遅いです。他のソリューションの方がおそらく優れています。

于 2012-10-22T06:11:43.033 に答える
1

以下は、動的に必要なソート関数を作成する必要があります。

ParameterExpression pe = Expression.Parameter(typeof(Report), "x");
LambdaExpression le = Expression.Lambda(
    Expression.PropertyOrField(pe, sort.Field),
    new List<ParameterExpression>() {pe});

var leCompiled = (Func<Report, string>)le.Compile();                

return sort.Dir == "asc" ? reports.OrderBy(leCompiled) : reports.OrderByDescending(leCompiled);

これは、x => x.ReportProperty の形式で Func デリゲートを作成します。ReportProperty は、sort.Field の値です。

于 2012-10-22T06:13:41.507 に答える
1

Marc Gravell には、 FastMemberという素晴らしい小さなライブラリがあります。次のように使用できます。

private IQueryable<Report> SortReports(IQueryable<Report> reports,KendoSort sort)
{
    var accessor = TypeAccessor.Create(typeof(Report));
    return sort.Dir == "asc" ? 
        reports.OrderBy(x => accessor[x,sort.Field]) : 
        reports.OrderByDescending(x => accessor[x,sort.Field]));
}
于 2012-10-22T05:49:34.157 に答える