我有一个集合,类型为
我想能够在运行时根据用户决定使用的任何分组字段动态地完成这个操作:
我在这里找到了大部分我需要的答案,dtb 在这里回答了这个问题:Linq GroupBy - how to specify the grouping key at runtime? 这个方法很好用:
除了我不知道
我已经阅读了很多SO帖子,大部分似乎适用于IQueryable和LinqToSQL。
使用Expression类似乎是实现这一目标的好方法,但是在编译时我不知道我的组参数的名称或数据类型,有没有办法做到这一点?
我感激任何朝正确方向的推动。
编辑:
使用Polity的解决方案,我创建了一个扩展方法来实现我一直想做的事情:
感谢Polity和所有回答者!
IEnumerable<Transaction>
。 Transaction 有几个属性,例如 TransactionId(Int64)、PaymentMethod(字符串)和 TransactionDate(DateTime)。我想能够在运行时根据用户决定使用的任何分组字段动态地完成这个操作:
transactions.GroupBy(x => x.PaymentMethod)
。我在这里找到了大部分我需要的答案,dtb 在这里回答了这个问题:Linq GroupBy - how to specify the grouping key at runtime? 这个方法很好用:
var arg = Expression.Parameter( typeof( Transaction ), "transaction" );
var body = Expression.Property( arg, "PaymentMethod" );
var lambda = Expression.Lambda<Func<Transaction, string>>( body, arg );
var keySelector = lambda.Compile();
var groups = transactions.GroupBy( keySelector );
除了我不知道
Expression.Lambda<Func<Transaction, string>>
中的Func返回类型是什么之外,其他都清楚了。 在这个示例中,它是字符串,但它也可能是Int64、decimal、DateTime等。 我不能使用Object作为返回类型,因为我可能有值类型。我已经阅读了很多SO帖子,大部分似乎适用于IQueryable和LinqToSQL。
使用Expression类似乎是实现这一目标的好方法,但是在编译时我不知道我的组参数的名称或数据类型,有没有办法做到这一点?
我感激任何朝正确方向的推动。
编辑:
使用Polity的解决方案,我创建了一个扩展方法来实现我一直想做的事情:
public static IEnumerable<IGrouping<object, T>> GroupBy<T>( this IEnumerable<T> items, string groupByProperty )
{
var arg = Expression.Parameter( typeof(T), "item" );
var body = Expression.Convert( Expression.Property( arg, groupByProperty ), typeof( object ) );
var lambda = Expression.Lambda<Func<T, object>>( body, arg );
var keySelector = lambda.Compile();
var groups = items.GroupBy( keySelector );
return groups;
}
感谢Polity和所有回答者!