首页 文章

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

提问于
浏览
3

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

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

我有一个名为 dataList<Item> . 我想做的事情就是检索由 A 分组的 X 的总和,或 XYZ 的总和,按 AB 分组 . 但是进入分组的哪些字段应该能够以某种方式在运行时指定 .

2 回答

  • 5

    获取Dynamic 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 ) ) );
    }
    
  • 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();
    

    用法:

    var result = source.GroupBy(keySelector);
    

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

相关问题