我正在尝试使用多列来排序查询。以下是我的代码和参数值。它在我尝试添加两个带有错误的表达式的行中失败:
没有为类型'System.String'定义二元运算符Add 和'System.Single'。
非常感谢任何帮助!!
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);
}
答案 0 :(得分:1)
您需要在外层使用OrderBy
/ ThenBy
链接表达式,而不是内层。方法如下:
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);
}