2014-09-28 3 views
1

Я хочу использовать лямбда-выражение для сортировки IEnumerable произвольного типа сущности произвольным именем столбца/поля.Динамически создавать сортировку выражения Лямбда

У меня есть этот вид функция:

public static IEnumerable<T> SortByFieldName<T>(IEnumerable<T> target, string sortPropertyName, string sortDirection) 
    { 
     if (!String.IsNullOrEmpty(sortPropertyName)) 
     { 
      Expression<Func<T, object>> sortExpression = GetSortLambda<T>(sortPropertyName); 
      switch (sortDirection.ToLower()) 
      { 
       case "a": 
        return target.AsQueryable<T>().OrderBy(sortExpression); 
       case "d": 
        return target.AsQueryable<T>().OrderByDescending(sortExpression); 
       default: 
        return target; 
      } 
     } 
     return target; 
    } 

с этой функцией, чтобы создать выражение (модифицированное из другого ответа здесь)

 public static Expression<Func<T,object>> GetSortLambda<T>(string propertyPath) 
    { 
     var param = Expression.Parameter(typeof(T), "p"); 
     var parts = propertyPath.Split('.'); 
     Expression parent = param; 
     foreach (var part in parts) 
     { 
      parent = Expression.Property(parent, part); 
     } 

     var sortExpression = Expression.Lambda<Func<T, object>>(parent, param); 
     return sortExpression; 
    } 

Это работает, как ожидается, для любого пути свойства, устраняющий к string, но для целых чисел (и реже для булевых) генерируется следующая ошибка (в случае свойства Int32):

Выражение типа «System.Int32» не может быть использован для возвращения типа «System.Object»

Это, я думаю, потому, что выражение возвращается в

Expression<Func<T,object>> 

, но я не могу выяснить, как это преодолеть - object должен охватывать все типы собственности, не так ли?

Возможно, я смогу сделать это с отражением, получив PropertyInfo (и тем самым напечатать) для целевого столбца, но я всегда предпочитаю избегать отражения, если это возможно.

Любые рекомендации/предложения оценены!

ответ

3

Вам может понадобиться Convert выражение, если вы имеете дело с типами значений, таких как целые числа или даты:

public static Expression<Func<T, object>> GetSortLambda<T>(string propertyPath) 
{ 
    var param = Expression.Parameter(typeof(T), "p"); 
    var parts = propertyPath.Split('.'); 
    Expression parent = param; 
    foreach (var part in parts) 
    { 
     parent = Expression.Property(parent, part); 
    } 

    if (parent.Type.IsValueType) 
    { 
     var converted = Expression.Convert(parent, typeof(object)); 
     return Expression.Lambda<Func<T, object>>(converted, param); 
    } 
    else 
    { 
     return Expression.Lambda<Func<T, object>>(parent, param); 
    } 
} 
+0

спасибо! Делает смысл и работает всегда приятное сочетание :-) – Serexx

Смежные вопросы