【问题标题】:Linq sorting with multiple column names in c#在 C# 中使用多个列名进行 Linq 排序
【发布时间】:2013-09-16 08:55:11
【问题描述】:

我想用 Linq 对多列进行排序

我使用this link作为参考,用于按列名对单列进行排序。

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

这是我目前正在做的事情

  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);
  }

我收到以下错误 -

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

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

【问题讨论】:

  • 那么你为什么试图打电话给Expression.Add

标签: c# sql linq sorting entity-framework-4


【解决方案1】:

不清楚您为什么首先尝试致电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);

我还建议将methodtypesexpprops 的声明也移到循环内部...并删除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 方法。然后,您只需要在任何时候建立一个单一的属性访问表达式树。

【讨论】:

  • 我知道那里不需要它,但我只是按原样发布了我的代码以显示我正在尝试的内容。
  • @NikhilChavan:但是为什么你在尝试呢?如果您知道不必要的操作会导致您出现问题,为什么不直接删除它呢?有关示例代码,请参阅我的编辑。
  • 感谢您的建议,我会尝试您的建议并检查是否有效。谢谢。
猜你喜欢
  • 2018-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-10
  • 1970-01-01
  • 1970-01-01
  • 2020-06-05
相关资源
最近更新 更多