Linq GroupBy – 如何在运行时指定分组键?

是否有一种很好的方法可以在运行时确定分组键的Linq GroupBy ? 例如,我希望从用户选择的字段列表构建分组键 – 您可以这样做吗? 我知道如果我将所有内容转换为字符串表,我可以轻松地完成它,但我想知道是否有一种优雅或聪明的方法来实现这一点。

 class Item { public int A, B; public DateTime D; public double X, Y, Z; } 

我有一个名为List data 。 我想做一些事情,比如检索由A分组的X的总和,或者用AB分组的XYZ的总和。 但是进入分组的哪些字段应该能够以某种方式在运行时指定。

获取动态LINQ代码并使用它的扩展,允许您使用字符串指定keySelector。

 var query = db.Foo.GroupBy( "{0}", "GroupedProperty", groupKey ); 

如果要返回按键分组的整个对象,您可能还需要考虑添加自己的扩展。

 public static IQueryable GroupByComplete( this IQueryable source, string keySelector, params object[] values ) { if (source == null) throw new ArgumentNullException( "source" ); if (keySelector == null) throw new ArgumentNullException( "keySelector" ); LambdaExpression keyLambda = DynamicExpression.ParseLambda( source.ElementType, null, keySelector, values ); return source.Provider.CreateQuery( Expression.Call( typeof( Queryable ), "GroupBy", new Type[] { source.ElementType, keyLambda.Body.Type }, source.Expression, Expression.Quote( keyLambda ) ) ); } 

您只需在运行时构造一个Func

 var arg = Expression.Parameter(typeof(Item), "item"); var body = Expression.Property(arg, "D"); var lambda = Expression.Lambda>(body, arg); var keySelector = lambda.Compile(); 

用法:

 var result = source.GroupBy(keySelector); 

如果在编译时不知道属性的类型,它会稍微(但不是很多)变得更难。