将第二组按关键字字段添加到现有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",我该如何将其添加到现有的表达式中?
您有一个问题,因为编译器对常规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();
}