C# 动态创建排序Lambda表达式

C# 动态创建排序Lambda表达式,c#,linq,sorting,dynamic,lambda,C#,Linq,Sorting,Dynamic,Lambda,我想使用lambda表达式按任意列/字段名对任意实体类型的IEnumerable进行排序 我有这个排序功能: public static IEnumerable<T> SortByFieldName<T>(IEnumerable<T> target, string sortPropertyName, string sortDirection) { if (!String.IsNullOrEmpty(sortPropertyName))

我想使用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;
    }
公共静态IEnumerable SortByFieldName(IEnumerable目标、字符串sortPropertyName、字符串sortDirection)
{
如果(!String.IsNullOrEmpty(sortPropertyName))
{
表达式sortExpression=GetSortLambda(sortPropertyName);
开关(sortDirection.ToLower())
{
案例“a”:
返回target.AsQueryable().OrderBy(sortExpression);
案例“d”:
返回target.AsQueryable().OrderByDescending(sortExpression);
违约:
回报目标;
}
}
回报目标;
}
使用此函数创建表达式(根据此处的另一个答案修改)

公共静态表达式GetSortLambda(字符串属性路径)
{
var param=表达式参数(类型(T),“p”);
var parts=propertyPath.Split('.');
表达式parent=param;
foreach(var零件中的零件)
{
父项=表达式.属性(父项,零件);
}
var sortExpression=Expression.Lambda(父级,参数);
返回排序表达式;
}
对于解析为字符串的任何属性路径,这都可以正常工作,但对于整数(对于布尔值,则不太常见),会生成以下错误(对于Int32属性):

“System.Int32”类型的表达式不能用于返回类型“System.Object”

我认为这是因为表达式返回为

Expression<Func<T,object>> 
表达式
但我不知道如何克服这个问题-
对象
应该涵盖所有属性类型,不是吗

我可能可以通过反射来实现这一点,获得目标列的PropertyInfo(以及相应的类型),但如果可能的话,我总是选择避免反射

任何指导/建议都将不胜感激

如果处理整数或日期等值类型,则可能需要使用表达式:

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);
    }
}
公共静态表达式GetSortLambda(字符串属性路径)
{
var param=表达式参数(类型(T),“p”);
var parts=propertyPath.Split('.');
表达式parent=param;
foreach(var零件中的零件)
{
父项=表达式.属性(父项,零件);
}
if(parent.Type.IsValueType)
{
var converted=Expression.Convert(父级,typeof(对象));
返回表达式.Lambda(已转换,参数);
}
其他的
{
返回表达式.Lambda(父,参数);
}
}
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);
    }
}