关于group by多字段分组动态表达式生成
`using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
public class MyItem
{
public string Key1 { get; set; }
public int Key2 { get; set; }
public string Value { get; set; }
}
public class Program
{
public static void Main()
{
List
{
new MyItem { Key1 = "A", Key2 = 1, Value = "Item1" },
new MyItem { Key1 = "A", Key2 = 1, Value = "Item2" },
new MyItem { Key1 = "B", Key2 = 2, Value = "Item3" },
// ... 其他项
};
// 假设这些是在运行时确定的分组键属性名
string[] groupKeys = new[] { "Key1", "Key2" };
// 构建动态分组的表达式
var param = Expression.Parameter(typeof(MyItem), "item");
var keySelector = Expression.New(
typeof(Tuple<string, int>).GetConstructor(new[] { typeof(string), typeof(int) }),
groupKeys.Select(key => Expression.PropertyOrField(param, key))
.Cast<Expression>()
.ToArray()
);
var query = items.AsQueryable()
.GroupBy(Expression.Lambda<Func<MyItem, Tuple<string, int>>>(keySelector, param))
.Select(group => new
{
Key = group.Key,
Count = group.Count(),
// 可以选择其他聚合操作,如 Sum, Average 等
});
// 注意:由于我们使用了 IQueryable 和 Expression,这个查询实际上还没有执行
// 我们需要遍历结果来触发查询执行
foreach (var group in query)
{
Console.WriteLine($"Key: ({group.Key.Item1}, {group.Key.Item2}), Count: {group.Count}");
}
// 注意:上面的代码在 .NET Core 或更高版本中可能需要一些调整,
// 因为 Tuple 类型在 .NET Core 中默认是不可变的,并且可能需要使用 ValueTuple 或自定义类型
// 这里为了简单起见,我使用了 Tuple。
// 在实际应用中,你可能想要定义一个具有适当属性的具体类来代替 Tuple
}
}`