【问题标题】:Sorting IEnumerable using LINQ使用 LINQ 对 IEnumerable 进行排序
【发布时间】:2012-01-28 22:14:54
【问题描述】:

关于 SO 有很多类似的问题,但我没有看到适合我情况的问题...

我想知道为什么这不能对 Premise 对象的 IEnumerable 进行排序:

sortedPremiseList = from p in premiseList
                 orderby (string.Format("{0} {1}", orderBy, sortOrder))
                  select p;

我为 orderBy 参数传入一个有效的 p.property,为 sortOrder 参数传入“升序”或“降序”

如果我不能像这样以有限的方式“动态化”我的 LINQ,除了一个又大又丑的 Switch 语句或类似的东西之外,还有什么选择?

非常感谢您的宝贵时间。

【问题讨论】:

  • string.Format的参数不应该是p.OrderBy和p.sortOrder吗?
  • Dynamic LINQ OrderBy 由 Marc Gravell 在 [this answer][1] 中为 IEnumerable 提供。 [1]:stackoverflow.com/questions/41244/dynamic-linq-orderby
  • 似乎对我来说最好的解决方案是按照 hypermush 的建议使用 Marc 的代码。

标签: c# linq sorting sql-order-by


【解决方案1】:

我认为您正在结合查询表示法和点表示法。为此,请尝试仅使用点符号:

sortedPremiseList = premiseList
           .OrderBy(p => string.Format("{0} {1}", p.orderBy, p.sortOrder));

【讨论】:

    【解决方案2】:

    我认为您需要在 string.Format() 调用中引用 p,如下所示:

    sortedPremiseList = from p in premiseList
        orderby (string.Format("{0} {1}", p.orderBy, p.sortOrder))
        select p;
    

    【讨论】:

      【解决方案3】:

      我想我明白你在这里的要求。您想从字符串参数构造 LINQ 查询

      好的。我喜欢挑战。

      IComparable GetPropValue( object src, string propName )
      {
        return (IComparable)src.GetType( ).GetProperty( propName ).GetValue( src, null );
      }
      
      IEnumerable<Premise> SortMyPremises(IEnumerable<Premise> premises, string propertyName, string ascendingOrDescending) 
      {
        return ascendingOrDescending = "ascending" 
          ? premises.OrderBy(p => GetPropValue(p, propertyName)) 
          : premises.OrderByDescending(p => GetPropValue(p, propertyName));
      }
      

      您编写它的方式不起作用的原因是 LINQ 表达式在编译时被转换为代码,并且您传递给它的字符串直到运行时才被评估。

      【讨论】:

        【解决方案4】:

        这对我有用:

        public static IEnumerable<TEntity> OrderBy<TEntity>(this IEnumerable<TEntity> source, string orderByProperty,
                                    bool desc)
                {
                    string command = desc ? "OrderByDescending" : "OrderBy";
                    var type = typeof(TEntity);
                    var property = type.GetProperty(orderByProperty);
                    var parameter = Expression.Parameter(type, "p");
                    var propertyAccess = Expression.MakeMemberAccess(parameter, property);
                    var orderByExpression = Expression.Lambda(propertyAccess, parameter);
                    var resultExpression = Expression.Call(typeof(Queryable), command, new Type[] { type, property.PropertyType },
                                                  source.AsQueryable().Expression, Expression.Quote(orderByExpression));
                    return source.AsQueryable().Provider.CreateQuery<TEntity>(resultExpression);
                }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-10-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多