You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改自定义OrderBy Lambda表达式,实现按集合属性Count()排序?

修改OrderBy Lambda表达式方法以支持集合属性按Count()排序

现有方法可生成针对普通属性的OrderBy表达式,但需扩展逻辑,当排序属性为集合类型时,自动调用Count()方法生成排序表达式。同时修正原代码中冗余且错误的属性获取逻辑。

修改后的完整代码

public IOrderedQueryable<T> createLambdaOrderBy<T>(IQueryable<T> source, PropertyInfo orderByProperty, bool desc = false)
{
    string command = desc ? "OrderByDescending" : "OrderBy";
    var type = typeof(T);
    var property = orderByProperty; // 直接使用传入的PropertyInfo参数
    ParameterExpression parameter = Expression.Parameter(type, "p");
    MemberExpression propertyAccess = Expression.MakeMemberAccess(parameter, property);

    // 判断属性是否为集合类型(实现IEnumerable),排除string类型
    var propertyType = property.PropertyType;
    if (typeof(System.Collections.IEnumerable).IsAssignableFrom(propertyType) && propertyType != typeof(string))
    {
        // 根据集合类型获取对应的Count()扩展方法
        MethodInfo countMethod;
        if (propertyType.IsGenericType)
        {
            // 泛型集合:获取带泛型参数的Count方法
            countMethod = typeof(Enumerable).GetMethods()
                .First(m => m.Name == "Count" && m.GetParameters().Length == 1)
                .MakeGenericMethod(propertyType.GetGenericArguments()[0]);
        }
        else
        {
            // 非泛型集合:获取针对IEnumerable的Count方法
            countMethod = typeof(Enumerable).GetMethod("Count", new[] { typeof(System.Collections.IEnumerable) });
        }

        // 构建调用Count()的表达式节点
        propertyAccess = Expression.Call(countMethod, propertyAccess);
    }

    LambdaExpression orderByExpression = Expression.Lambda(propertyAccess, parameter);
    // 调整泛型参数:将排序结果类型改为Count()返回的int类型
    var resultExpression = Expression.Call(typeof(Queryable), command, 
        new Type[] { type, propertyAccess.Type }, 
        source.Expression, Expression.Quote(orderByExpression));
    return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(resultExpression);
}

关键改动说明

  • 集合类型识别:检查属性是否实现IEnumerable接口,同时排除string类型(避免将字符串误判为集合)。
  • Count()方法适配:针对泛型和非泛型集合分别获取对应的Count扩展方法,保证兼容不同类型的集合。
  • 表达式重构:若为集合属性,在原属性访问表达式基础上,构建调用Count()的表达式节点,替换原直接属性访问逻辑。
  • 类型参数修正:创建OrderBy表达式时,将排序结果类型改为Count()返回的int类型,确保表达式类型匹配。

修改后,当传入集合类型的排序属性时,生成的表达式将变为:

.OrderBy(p => p.SomeProperty.Count())

普通属性则保持原有排序逻辑不变。

内容的提问来源于stack exchange,提问作者patsy2k

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 01:44:55