我希望使用Lambda表达式根据任意列名/字段名对任意实体类型的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;
}
这对于任何解析为字符串的属性路径都能如预期般工作,但是对于整数(以及较少出现的布尔值),将会生成以下错误(在Int32属性的情况下):
类型为'System.Int32'的表达式不能用于返回类型为'System.Object'
我认为原因在于被返回的表达式被视为
Expression<Func<T,object>>
但我无法想出如何克服这个问题 - object
应该涵盖所有属性类型,不是吗?
我可能可以通过反射来实现此目的,获取目标列的PropertyInfo(及其类型),但如果可能的话,我总是选择避免使用反射。
任何指导/建议都将不胜感激!