【问题标题】:Dynamically Create Sort Lambda Expression动态创建排序 Lambda 表达式
【发布时间】:2014-09-28 21:38:15
【问题描述】:

我想使用 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(以及类型),但如果可能,我总是选择避免反射。

任何指导/建议表示赞赏!

【问题讨论】:

    标签: c# linq sorting dynamic lambda


    【解决方案1】:

    如果您处理整数或日期等值类型,您可能需要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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多