2016-10-25 4 views
0

複数の列を使用してクエリを注文しようとしています。以下は私のコードとパラメータ値です。エラーが発生した2つの式を追加しようとする行でエラーが発生します。OrderByのラムダ式を結合する

The binary operator Add is not defined for the types 'System.String' and 'System.Single'.

ご協力いただければ幸いです!あなたが外側のレベルではなく、内側のレベルにOrderBy/ThenByでチェーンにあなたの表現を必要とする

sortColumn = "table1.column1,table2.column1,column3" 

public static IQueryable<T> OrderBy<T>(this IQueryable<T> query, string sortColumn, string direction) { 
    string methodName = string.Format("OrderBy{0}", direction.ToLower() == "asc" ? "" : "descending"); 
    ParameterExpression parameter = Expression.Parameter(query.ElementType, "p"); 
    MemberExpression memberAccess = null; 
    LambdaExpression orderByLambda = null; 

    foreach (var fields in sortColumn.Split(',')) { 
     memberAccess = null; 
     foreach (var property in fields.Split('.')) { 
      memberAccess = MemberExpression.Property(memberAccess ?? (parameter as Expression), property); 
     } if (orderByLambda == null) { 
      orderByLambda = Expression.Lambda(memberAccess, parameter); 
     } else { 
      orderByLambda = Expression.Lambda(Expression.Add(orderByLambda.Body, Expression.Lambda(Expression.Invoke(Expression.Lambda(memberAccess, parameter), parameter), parameter).Body), parameter); 
     } 
    } 
    MethodCallExpression result = Expression.Call(
       typeof(Queryable), 
       methodName, 
       new[] { query.ElementType, memberAccess.Type }, 
       query.Expression, 
       Expression.Quote(orderByLambda)); 
    return query.Provider.CreateQuery<T>(result); 
} 
+3

使用 'ThenBy'た後、あなたの最初の' OrderBy' –

+5

おそらく、あなたは、[並べ替え/ ThenBy/ThenByを呼び出すべきであるだけではなく、単一のOrderByの呼び出しを使用しようとしている:ここではどのように? –

+0

ありがとう、私はThenByもオプションですが、私はそれが可能だと信じていますが、構文にこだわると思うので、これを実際にやりたいのです。 – ecasper

答えて

1

public static IQueryable<T> OrderBy<T>(this IQueryable<T> query, string sortColumn, string direction) { 
    var methodNameFirst = string.Format("OrderBy{0}", direction.ToLower() == "asc" ? "" : "descending"); 
    var methodNameContinue = string.Format("ThenBy{0}", direction.ToLower() == "asc" ? "" : "descending"); 
    ParameterExpression parameter = Expression.Parameter(query.ElementType, "p"); 
    Expression result = query.Expression; 
    var methodName = methodNameFirst; 
    foreach (var fields in sortColumn.Split(',')) { 
     Expression memberAccess = null; 
     foreach (var property in fields.Split('.')) { 
      memberAccess = MemberExpression.Property(memberAccess ?? (parameter as Expression), property); 
     } 
     LambdaExpression orderByLambda = Expression.Lambda(memberAccess, parameter); 
     result = Expression.Call(
      typeof(Queryable), 
      methodName, 
      new[] { query.ElementType, memberAccess.Type }, 
      result, 
      Expression.Quote(orderByLambda)); 
     methodName = methodNameContinue; 
    } 
    return query.Provider.CreateQuery<T>(result); 
} 
+0

私はこれをコンパイルしようとしていないので、コンパイルする前にコードを少し調整する必要があります。ここでの主なことは、個々のメンバ式を連鎖しようとするのではなく、 'OrderBy' /' ThenBy'をプログラム的に連鎖させる方法のアイデアを与えることです。タイブレークロジック)、実行時に成功するとは限りません。 – dasblinkenlight

+0

ありがとう!!私はそれを別のやり方で見ていて、あなたの答えは仕事を完璧にしています。 – ecasper

+0

私が変更したのは、式memberAccess =を準拠させるためにnullを設定することだけでした。 – ecasper