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

toa*_*ven 3 c# linq group-by

是否有一种很好的方法可以GroupBy在运行时确定分组键的Linq ?例如,我希望从用户选择的字段列表构建分组键 - 你能这样做吗?我知道我可以很容易地做到这一点,如果我转换一切字串的表,但我想知道是否有其他方式来完成这个优雅的或聪明的办法.

class Item
{
    public int A, B;
    public DateTime D;
    public double X, Y, Z;
}
Run Code Online (Sandbox Code Playgroud)

List<Item>有个叫data.我想要做的事情一样检索的总和X按分组A,或的总和X,Y以及Z通过分组AB.但是应该能够以某种方式在运行时指定哪些字段进入分组.

dtb*_*dtb 8

您只需在运行时构造一个Func <Item,TKey>:

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();
Run Code Online (Sandbox Code Playgroud)

用法:

var result = source.GroupBy(keySelector);
Run Code Online (Sandbox Code Playgroud)

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


tva*_*son 5

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

var query = db.Foo.GroupBy( "{0}", "GroupedProperty", groupKey );
Run Code Online (Sandbox Code Playgroud)

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

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 ) ) );
}
Run Code Online (Sandbox Code Playgroud)