排序IEnumerable使用LINQ

本文关键字:LINQ 使用 IEnumerable 排序 | 更新日期: 2023-09-27 18:18:59

在SO上有很多类似的问题,但我没有看到一个适合我的情况…

我想知道为什么这不能排序IEnumerable的前提对象:

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

我为orderBy参数传递了一个有效的p属性,为sortOrder参数传递了"升序"或"降序"

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

感谢您的宝贵时间。

排序IEnumerable使用LINQ

我想你把查询表示法和点表示法结合起来了。对于这种情况,尝试只使用点表示法:

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

我认为你需要在string.Format()调用中引用p,像这样:

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

我想我明白你的要求。您希望从字符串参数

构造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表达式在编译时被转换成代码,而你传递给它的字符串直到运行时才被计算。

这对我有用:

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