对于具有对象键的基本类型,IQueryable GroupBy Lambda表达式失败

时间:2017-09-29 12:49:08

标签: c# linq expression-trees iqueryable

我正在为IQueryable<TSource>创建Lambda Expression,以下是我的扩展方法代码,我需要调用它:

queryableData.GroupBy<int,Product>("ID")

queryableData.GroupBy<string,Product>("Name")

public static IQueryable<IGrouping<TKey,TSource>> GroupBy<TKey,TSource>(this IQueryable<TSource> queryable, string propertyName)
    {
        // Access the propertyInfo, using Queryable Element Type (Make it Case insensitive)
        var propInfo = queryable.ElementType.GetProperty(propertyName,BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);

        // Access the Collection / Queryable Type
        var collectionType = queryable.ElementType;

        // Creating Group Parameter Expression
        var groupParameterExpression = Expression.Parameter(collectionType, "g");

        // Create MemberEXpression with the Property (access the property of a Type)
        var propertyAccess = Expression.MakeMemberAccess(groupParameterExpression, propInfo);

        // Create Lambda Expression
        var lambdaExpression = Expression.Lambda<Func<TSource,TKey>>(propertyAccess, groupParameterExpression);

        // Return GroupBy result
        return queryable.GroupBy(lambdaExpression);
    }

我的目标是生成Expression<Func<TSource,object>>而不是Expression<Func<TSource,TKey>>,以便可以在不提供密钥类型的情况下调用它,以下是代码:

public static IQueryable<IGrouping<object, TSource>> GroupByObjectKey<TSource>(this IQueryable<TSource> queryable, string propertyName)
    {
        // Access the propertyInfo, using Queryable Element Type (Make it Case insensitive)
        var propInfo = queryable.ElementType.GetProperty(propertyName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);

        // Access the Collection / Queryable Type
        var collectionType = queryable.ElementType;

        // Creating Group Parameter Expression
        var groupParameterExpression = Expression.Parameter(collectionType, "g");

        // Create MemberEXpression with the Property (access the property of a Type)
        var propertyAccess = Expression.MakeMemberAccess(groupParameterExpression, propInfo);

        // Create Lambda Expression
        var lambdaExpression = Expression.Lambda<Func<TSource, object>>(propertyAccess, groupParameterExpression);

        // Return GroupBy result
        return queryable.GroupBy(lambdaExpression);
    }

现在我能够使其适用于字符串类型,如下所示:

queryableData.GroupBy<Product>("Name")

但它跟随调用整数类型失败,异常如下所述:

queryableData.GroupBy<Product>("Id")

Expression of type 'System.Int32' cannot be used for return type 'System.Object'

这是类型转换的一个明显例子,但我很惊讶为什么一个类型会拒绝转换为Object基类,可能是什么理由,任何指针/建议

1 个答案:

答案 0 :(得分:1)

正如评论已经指出的那样,您需要将转化添加到object

var convertToObject = Expression.Convert(propertyAccess, typeof(object));

var lambdaExpression = Expression.Lambda<Func<TSource, object>>(convertToObject, groupParameterExpression);