2016-10-07 3 views
2

私はリフレクションを使って表現することによって順序を生成するための方法を見つけることができたが、それは1つのプロパティレベルのために働くのでAddress.Streetなどの複雑な並べ替えのために動作しません。この変換文字列を使用して式でEF順序を作成する方法は?

"Address.Street" => (p) => p.Address.Street 
"Name" => (p) => p.Name 

をachiveしようとしています。

これを行う方法はありますか?私はラムダ式をコンパイルしているのを見ましたが、このケースではどのように動作させるのか理解できませんでした。

+1

これを参照してください:ここで

は、カスタム拡張メソッドにカプセル化されたものがすべてですhttp://stackoverflow.com/questions/307512/how-do-i-apply-orderby-on-an-遺伝子内の列名を使用することができます –

+0

@Sumit Maingi:それは 'Address.Street'のためには機能しません:( – StackOverflower

答えて

9

式を作成するのは難しくありませんが、プロパティの型(したがってセレクタ式の結果の型)がわからない場合は、対応するOrderBy(Descending)/ThenBy(Descendig)メソッドにバインドする方法が難しいです。

public static partial class QueryableExtensions 
{ 
    public static IOrderedQueryable<T> OrderByMember<T>(this IQueryable<T> source, string memberPath) 
    { 
     return source.OrderByMemberUsing(memberPath, "OrderBy"); 
    } 
    public static IOrderedQueryable<T> OrderByMemberDescending<T>(this IQueryable<T> source, string memberPath) 
    { 
     return source.OrderByMemberUsing(memberPath, "OrderByDescending"); 
    } 
    public static IOrderedQueryable<T> ThenByMember<T>(this IOrderedQueryable<T> source, string memberPath) 
    { 
     return source.OrderByMemberUsing(memberPath, "ThenBy"); 
    } 
    public static IOrderedQueryable<T> ThenByMemberDescending<T>(this IOrderedQueryable<T> source, string memberPath) 
    { 
     return source.OrderByMemberUsing(memberPath, "ThenByDescending"); 
    } 
    private static IOrderedQueryable<T> OrderByMemberUsing<T>(this IQueryable<T> source, string memberPath, string method) 
    { 
     var parameter = Expression.Parameter(typeof(T), "item"); 
     var member = memberPath.Split('.') 
      .Aggregate((Expression)parameter, Expression.PropertyOrField); 
     var keySelector = Expression.Lambda(member, parameter); 
     var methodCall = Expression.Call(
      typeof(Queryable), method, new[] { parameter.Type, member.Type }, 
      source.Expression, Expression.Quote(keySelector)); 
     return (IOrderedQueryable<T>)source.Provider.CreateQuery(methodCall); 
    } 
+2

私はあなたに+100を与えることができたらいいと思います。 – StackOverflower

+2

あなたは大歓迎です:)あなたの言葉は、どんな仮想ポイントよりもはるかに価値があります! –

+0

私はあまりにも好きです。 IEnumerableバージョンを持つことも可能ですか?クライアントコードがなくても、メソッドを呼び出す前に.AsQueryable()を呼び出す必要はありませんか? – ManOfSteele

関連する問題