プロパティ名を文字列としてソートする

asp.net asp.net-core c# entity-framework-core linq

質問

私は自分のWeb APIがこのような文字列パラメータで出力をソートできるようにしたいと思います:

http://myapi.com/api/people?skip=0&take=50&orderBy=lastName&descending=true

私はAPIでページネーションサポート( skiptake )も行っているので、正しい結果がデータベースから来るように、 orderByパラメータとdescendingパラメータをSQLクエリに直接適用したいと思います。

しかしこれを行うとき、 orderByのパラメータを、文字列比較だけでソートしたいクラスの実際のプロパティと一致させようとすると、コードを管理するのが非常に難しくなります。

私は、新しいCore CLRを使ってこのコードをコンパイルしようとすると、LINQ to Entitiesと同様に新しいEF7で動作するはずのソリューションを見つけました。次のメッセージが表示されます。

エラーCS1503引数2: 'System.Linq.Expressions.Expression>'から 'string'に変換できません

失敗したソリューションのコードは、 OrderBy<T>メソッドです。

public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName)
{
    return source.OrderBy(ToLambda<T>(propertyName));
}

新しいCore CLRがこの試みをサポートしていないようです。ソリューションを新しいCLRと連携させる別の方法はありますか?そうでない場合は、EF7を使ってソートを有効にしなければならない他の選択肢は何ですか? if文またはswitch文は、入力文字列とプロパティ名を比較します。

受け入れられた回答

あなたのリンクからのソリューションは、ほとんどの時間LINQ to Entitiesで動作しない "Expression.Convert"を使用します。

ここには動作する拡張メソッドがあります:

public static IOrderedQueryable<TSource> OrderBy<TSource>(this IQueryable<TSource> source, string propertyName)
{
    // LAMBDA: x => x.[PropertyName]
    var parameter = Expression.Parameter(typeof(TSource), "x");
    Expression property = Expression.Property(parameter, propertyName);
    var lambda = Expression.Lambda(property, parameter);

    // REFLECTION: source.OrderBy(x => x.Property)
    var orderByMethod = typeof(Queryable).GetMethods().First(x => x.Name == "OrderBy" && x.GetParameters().Length == 2);
    var orderByGeneric = orderByMethod.MakeGenericMethod(typeof(TSource), property.Type);
    var result = orderByGeneric.Invoke(null, new object[] { source, lambda });

    return (IOrderedQueryable<TSource>)result;
}

免責事項 :私はGitHubのEF +プロジェクトのオーナーです。

私のリポジトリのプロパティ名で注文する他の方法を見つけることができます: GitHub

  • OrderByDescending
  • 次に、
  • その後、
  • AddOrAppendOrderBy
  • AddOrAppendOrderByDescending

編集 :サブ質問に答える

このようなものを使用してナビゲーションプロパティでソートすることは可能でしょうか?たとえば、プロパティ名 "NavigationProperty.PropertyName"

はい、文字列とループを分割してプロパティパスを使用して式を作成するか、実際の式評価を使用できます。

免責事項 :私はプロジェクトの所有者ですEval-Expressions.NET

このライブラリを使用すると、すべてのLINQメソッドを動的に実行できます。

参照: LINQ Dynamic

var result = list.OrderByDynamic(x => "NavigationProperty.PropertyName");


Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ