将第二组按关键字字段添加到现有Lambda表达式中

本文关键字:添加 Lambda 表达式 字段 关键字 二组 | 更新日期: 2023-09-27 18:30:14

我有一个Groupby表达式,我正在动态创建它,以便在LINQ查询中使用。目前,为了构建表达式,我使用以下代码:

var arg = Expression.Parameter(typeof(T), helper.getName());
var prop = Expression.Property(arg, "customerType");
var body = Expression.Convert(prop, typeof(object));
var lambda = Expression.Lambda<Func<Contact, object>>(body, arg);
var keySelector = lambda.Compile();

然后,我使用GroupBy中的keySelector进行LINQ查询。我的问题是,如果我想为这个表达式添加第二个分组标准,比如"salesStage",我该如何将其添加到现有的表达式中?

将第二组按关键字字段添加到现有Lambda表达式中

您有一个问题,因为编译器对常规GroupBy调用所做的是使用您定义的属性生成一个新的匿名类型。如果该类型不存在,则无法创建创建该类型对象的表达式。

但是,考虑到您正在将其用于LINQ to Objects,我们可以使用Tuple<>类型来生成分组密钥。希望您不需要对超过8个参数进行分组。

这里有一个生成分组函数的通用函数:

static Func<T, object> BuildGrouper<T>(IEnumerable<string> properties) {
    var arg = Expression.Parameter(typeof(T), helper.getName());
    // This is the list of property accesses we will be using
    var parameters = properties.Select(propName => Expression.Property(arg, propName)).ToList();
    // Find the correct overload of Tuple.Create.
    // This will throw if the number of parameters is more than 8!
    var method = typeof(Tuple).GetMethods().Where(m => m.Name == "Create" && m.GetParameters().Length == parameters.Count).Single();
    // But it is a generic method, we need to specify the types of each of the arguments
    var paramTypes = parameters.Select(p => p.Type).ToArray();
    method = method.MakeGenericMethod(paramTypes);
    // Invoke the Tuple.Create method and return the Func
    var call = Expression.Call(null, method, parameters);
    var lambda = Expression.Lambda<Func<T, object>>(call, arg);
    return lambda.Compile();
}