我有一个集合,是IEnumerable<Transaction>
。交易有几个属性,如TransactionId(Int64),PaymentMethod(字符串)和TransactionDate(日期时间)LINQ的 - 动态的GroupBy与IEnumerable的<T>
我希望能够在运行时动态完成这个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);
只是我不知道的返回类型的类型Func在Expression.Lambda<Func<Transaction, string>>
。它在这个例子中是字符串,但它可能是Int64,decimal,DateTime等。我不能使用Object作为返回类型,因为我可能有值类型。
我一直在阅读大量的SO职位,其中大部分似乎适用于IQueryable的和LinqToSQL。
使用表达式类好像做到这一点的好办法,但有没有办法做到这一点的时候,我不知道名称或在编译时我的组参数的数据类型?
我很欣赏任何在正确的方向微调。
编辑:
使用下面政体的解决方案,我创建了一个扩展方法做什么,我一直在努力做的事情:
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;
}
由于政体和大家谁回答!
你可以把这些代码放到一个通用的方法中,并将返回类型设置为通用参数的类型吗? – ojlovecd
如果我理解你的问题,我不这么认为。我所拥有的几乎全部是用户选择作为组密钥的属性的字符串名称。我想我必须使用一些反射来获得类型。 –
其中一位与我合作的人建议根据分组属性的类型创建一个switch语句,为所有值类型添加一个案例,并为它的类型添加默认使用对象。这会起作用,但我认为编码后需要淋浴。 –