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

编程入门 行业动态 更新时间:2024-10-27 11:27:19
对于具有对象键的基本类型,IQueryable GroupBy Lambda表达式失败(IQueryable GroupBy Lambda expression fails for primitive types with object key)

我正在为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>> ,这样可以在不提供Key类型的情况下调用它,以下是代码:

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基类,可能是什么原因,任何指针/建议

I am in process of creating Lambda Expression for an IQueryable<TSource>, following is my extension method code, which I need to call like:

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); }

My aim is to generate Expression<Func<TSource,object>> instead of Expression<Func<TSource,TKey>>, so that it can be called without providing the Key type, following is code:

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); }

Now I able to make it work for string type as follows:

queryableData.GroupBy<Product>("Name")

but it fails on following call for integer type with exception as stated underneath:

queryableData.GroupBy<Product>("Id")

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

This is a clear case of Type conversion, but I am surprised that why a type would refuse to be converted to Object base class, what could be the rationale, any pointer / suggestion

最满意答案

正如评论已经指出的那样,您需要向object添加转换:

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

As comments already pointed out, you need to add a conversion to object:

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

更多推荐

本文发布于:2023-08-04 19:50:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1421417.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:表达式   对象   类型   GroupBy   Lambda

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!