2011-12-28 6 views
4

Есть много подобных вопросов на SO, но я не вижу, что соответствует моим обстоятельствам ...Сортировка IEnumerable с помощью LINQ

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

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

Я передаю в допустимом p.property для аргумента OrderBy и «по возрастанию» или «по убыванию» для аргумента SortOrder

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

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

+0

не должны параметры в string.Format быть p.OrderBy и p.sortOrder? –

+2

Динамический LINQ OrderBy задан для IEnumerable Марком Гравелем в [этом ответе] [1]. [1]: http://stackoverflow.com/questions/41244/dynamic-linq-orderby – hypermush

+0

Похоже, лучшее решение для меня, чтобы использовать код Марка, как это было предложено hypermush. – theog

ответ

2

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

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

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

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

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

0

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

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); 
     } 
Смежные вопросы