C# LINQGroupBy-如何在运行时指定分组键?

C# LINQGroupBy-如何在运行时指定分组键?,c#,linq,group-by,C#,Linq,Group By,在运行时确定分组键的LinqGroupBy中,有没有一种好方法?e、 g.我希望分组键是从用户选择的字段列表中生成的-您可以这样做吗?我知道如果我把所有的东西都转换成一个字符串表,我可以很容易地做到,但我想知道是否有一种优雅或聪明的方法来实现这一点 class Item { public int A, B; public DateTime D; public double X, Y, Z; } 我有一个名为数据的列表。我想做一些事情,比如检索按A分组的X之和,或者检索按

在运行时确定分组键的Linq
GroupBy
中,有没有一种好方法?e、 g.我希望分组键是从用户选择的字段列表中生成的-您可以这样做吗?我知道如果我把所有的东西都转换成一个字符串表,我可以很容易地做到,但我想知道是否有一种优雅或聪明的方法来实现这一点

class Item
{
    public int A, B;
    public DateTime D;
    public double X, Y, Z;
}
我有一个名为
数据的
列表
。我想做一些事情,比如检索按
A
分组的
X
之和,或者检索按
A
B
分组的
X
Y
Z
之和。但是分组中的哪些字段应该能够在运行时以某种方式指定。

获取代码并使用扩展名,该扩展名允许您使用字符串指定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<Func<Item, DateTime>>(body, arg);
var keySelector = lambda.Compile();

如果您在编译时不知道属性的类型,它会变得稍微困难一些(但不会太困难)。

这看起来正是我想要的。看看源代码,我想它比我想象的要复杂得多,幸好我自己没有花太多时间来写:)我试着这么做,但无法理解语法,谢谢你的例子。这对我很有帮助-谢谢。如果您在编译时不知道Func的返回类型,您有什么选择?@NathanRatcliff您已经知道这个问题的答案了吗?
var result = source.GroupBy(keySelector);