Сортировка IEnumerable с использованием LINQ - PullRequest
4 голосов
/ 28 декабря 2011

Есть много похожих вопросов по SO, но я не вижу такой, которая соответствует моим обстоятельствам ...

Мне интересно, почему это не работает для сортировки объектов IEnumerable из Premise:

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

Я передаю действительное значение p.property для аргумента orderBy и "восходящий" или "нисходящий" для аргумента sortOrder

И если я не могу «динамизировать» свой LINQ ограниченным образом, как это, какая альтернатива есть, кроме большого уродливого оператора Switch или чего-то в этом роде?

Большое спасибо за ваше время.

Ответы [ 4 ]

2 голосов
/ 28 декабря 2011

Я думаю, что вы комбинируете нотацию запроса и нотацию точки. Для этого попробуйте придерживаться только точечного обозначения:

sortedPremiseList = premiseList
           .OrderBy(p => string.Format("{0} {1}", p.orderBy, p.sortOrder));
1 голос
/ 02 сентября 2012

Мне кажется, я понимаю, что вы просите здесь.Вы хотите построить запрос 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 преобразуется в код во время компиляции, а передаваемая строка не обрабатывается до времени выполнения.

1 голос
/ 28 декабря 2011

Я думаю, вам нужно сослаться на p внутри вашего string.Format() звонка, например:

sortedPremiseList = from p in premiseList
    orderby (string.Format("{0} {1}", p.orderBy, p.sortOrder))
    select p;
0 голосов
/ 17 апреля 2013

Это сработало для меня:

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