0

我想用 Linq 对多列进行排序

我使用这个链接作为参考,它用于按列名对单列进行排序。

我正在尝试使用此方法对具有列名的多个列进行排序。

这是我到目前为止所做的

  public static IQueryable<T> OrderByMultipleFields<T>(this IQueryable<T> q, Dictionary<string, bool> fieldsToSort)
  {
    var param = Expression.Parameter(typeof(T), "p");
    var prop = Expression.Property(param, fieldsToSort.First().Key);
    var exp = Expression.Lambda(prop, param);
    string methodAsc = "OrderBy";
    string methodDesc = "OrderByDescending";
    string method=string.Empty;
    Type[] types = new Type[] { q.ElementType, exp.Body.Type };
    var mce = q.Expression;
    int count = 0;
    foreach (var fieldName in fieldsToSort)
    {
      method = fieldName.Value ? methodAsc : methodDesc;
      prop = Expression.Property(param, fieldName.Key);
      exp = Expression.Lambda(prop, param);
      types = new Type[] { q.ElementType, exp.Body.Type };
      if (count == 0) {
        mce = Expression.Call(typeof(Queryable), method, types, q.Expression, exp);
      } else {
        mce = Expression.Add(mce, Expression.Call(typeof(Queryable), method, types, q.Expression, exp));
      }
      methodAsc = "ThenBy";
      methodDesc = "ThenByDescending";
      count++;
    }
    return q.Provider.CreateQuery<T>(mce);
  }

我收到以下错误 -

1[SortDemo.Data.User]' and 'System.Linq.IOrderedQueryable没有为类型“System.Linq.IOrderedQueryable 1[SortDemo.Data.User]”定义二元运算符 Add 。

实现此目的的正确方法是什么,或者是否有任何替代方法或方法。谢谢。

4

1 回答 1

0

目前尚不清楚您为什么要Add首先打电话。正常的排序代码中没有加法运算,所以表达式树的形式也不会有。

我怀疑你只是想替换这个:

if (count == 0)
{
    mce = Expression.Call(typeof(Queryable), method, types, q.Expression, exp);
}
else {
    mce = Expression.Add(mce, Expression.Call(typeof(Queryable), method, types, q.Expression, exp));
}

和:

mce = Expression.Call(typeof(Queryable), method, types, q.Expression, exp);

我还建议将 , 和 的声明也移到method循环types内部exp...props并删除count. 那会给你留下:

string methodAsc = "OrderBy";
string methodDesc = "OrderByDescending";
var mce = q.Expression;
foreach (var fieldName in fieldsToSort)
{
    var method = fieldName.Value ? methodAsc : methodDesc;
    var prop = Expression.Property(param, fieldName.Key);
    var exp = Expression.Lambda(prop, param);
    var types = new Type[] { q.ElementType, exp.Body.Type };
    mce = Expression.Call(typeof(Queryable), method, types, q.Expression, exp);
    methodAsc = "ThenBy";
    methodDesc = "ThenByDescending";
}

return q.Provider.CreateQuery<T>(mce);

我没有尝试过,但它比你以前拥有的更有价值。

要考虑的另一件事不是像这样构建整个表达式树,而是Queryable自己通过反射直接调用适当的方法。然后,您只需要在任何时候构建一个单一的属性访问表达式树。

于 2013-09-12T05:58:17.353 回答