C# linq 根据多字段动态Group by

server/2025/1/9 11:16:24/

实现类: 

public static class LinqHepler
{/// <summary>/// 根据单个字段动态Group/// </summary>/// <typeparam name="T"></typeparam>/// <param name="source"></param>/// <param name="propertyName"></param>/// <returns></returns>public static IEnumerable<IGrouping<object, T>> GroupByDynamic<T>(this IEnumerable<T> source, string propertyName){var parameter = Expression.Parameter(typeof(T), "p");var property = Expression.Property(parameter, propertyName);var lambda = Expression.Lambda(typeof(Func<T, object>), Expression.Convert(property, typeof(object)), parameter);var groupByMethod = typeof(Enumerable).GetMethods().Where(m => m.Name == "GroupBy" && m.GetParameters().Length == 2).First();var groupBy = groupByMethod.MakeGenericMethod(typeof(T), typeof(object));return (IEnumerable<IGrouping<object, T>>)groupBy.Invoke(null, new object[] { source, lambda.Compile() });}/// <summary>/// 多字段动态GroupBy/// </summary>/// <typeparam name="T">需要重写GetHashCode和Equals方法, 因为类是比较引用的,而常用于GroupBy操作的匿名类是比较值的</typeparam>/// <param name="source"></param>/// <param name="propertyNames"></param>/// <returns></returns>public static IEnumerable<IGrouping<T, T>> GroupByDynamic<T>(this IEnumerable<T> source, List<string> propertyNames) where T : class{if(propertyNames.IsNullOrEmpty())throw new ArgumentNullException("propertyNames");var parameter = Expression.Parameter(typeof(T), "p");var lambda = BuildSelector<T>(parameter, propertyNames);var groupByMethod = typeof(Enumerable).GetMethods().Where(m => m.Name == "GroupBy" && m.GetParameters().Length == 2).First();var groupBy = groupByMethod.MakeGenericMethod(typeof(T), typeof(T));return (IEnumerable<IGrouping<T, T>>)groupBy.Invoke(null, new object[] { source, lambda });}private static Func<T, T> BuildSelector<T>(ParameterExpression param, List<string> propertyNames){var memberBindings = new List<MemberBinding>(propertyNames.Count);foreach (var propertyName in propertyNames){var expressionProperty = Expression.Property(param, propertyName);memberBindings.Add(Expression.Bind(typeof(T).GetProperty(propertyName), expressionProperty));}var memberInit = Expression.MemberInit(Expression.New(typeof(T)), memberBindings);var lambda = Expression.Lambda<Func<T, T>>(memberInit, param);return lambda.Compile();}
}

使用方式:

var people = new List<Person>
{new Person { Name = "Alice",Six="男", Age = 30 },new Person { Name = "Alice",Six="男", Age = 20 },new Person { Name = "Bob",Six="男", Age = 30 },new Person { Name = "Bob",Six="男", Age = 25 },new Person { Name = "Charlie",Six="男", Age = 25 },new Person { Name = "Charlie",Six="男", Age = 25 }
};var groupFileds = new List<string>() { "Name", "Six" };
var groupedByName = people.GroupByDynamic(groupFileds).Select(t =>{var model = new Person(){Name = t.First().Name,Six = t.First().Six,Age = t.Sum(p => p.Age),Details = t.ToList(),};return model;}).ToList();
//需要重写GetHashCode和Equals方法, 因为类是比较引用的,而常用于GroupBy操作的匿名类是比较值的public class Person{public string? Name { get; set; }public string? Six { get; set; }public int Age { get; set; }public override int GetHashCode(){return $"{Name},{Six},{Age}".GetHashCode(); //需要用来分组的字段,或者全部字段}public override bool Equals(object? obj){if (obj == null)return false;if(!(obj is Person))return false;return this.GetHashCode() == obj.GetHashCode();}}


http://www.ppmy.cn/server/57.html

相关文章

【笔试强训】Day1 --- 数字统计 + 两个数组的交集 + 点击消除

文章目录 1. 数字统计2. 两个数组的交集3. 点击消除 1. 数字统计 【链接】&#xff1a;数字统计 解题思路&#xff1a;模拟&#xff0c;利用数学知识&#xff0c;计算每个数字中2出现的个数。&#xff08;这里也可以将数字转换成字符串来统计字符’2’出现的个数&#xff09…

穿越“至暗期”后,三只松鼠的“百亿路”稳了吗?

文 | 螳螂观察 作者 | 易不二 三只松鼠的高端性价比战略已经有了初步成效。 继交出20203年净利润高增的年报之后&#xff0c;2024年一季度&#xff0c;三只松鼠的营收与利润均实现了有史以来的最高增幅。 财报显示&#xff0c;2023年三只松鼠实现营收71.15亿元&#xff1b;…

html接入高德地图

1.申请key key申请地址&#xff1a;https://console.amap.com/dev/key/app 官方文档 https://lbs.amap.com/api/javascript-api-v2/summary 2.html接入示例 需要将YOUR_KEY替换成自己的key <!doctype html> <html> <head><meta charset"utf-…

Ai2024安装包(亲测可用)

目录 一、软件简介 二、软件下载 一、软件简介 Adobe illustrator&#xff0c;常被称为“AI”&#xff0c;是一种应用于出版、多媒体和在线图像的工业标准矢量插画的软件。作为一款非常好的矢量图形处理工具&#xff0c;该软件主要应用于印刷出版、海报书籍排版、专业插画、多…

docker安装ubuntu桌面端

docker compose 文件ubuntu.yml version: "3"services:ubuntu:image: ubuntu:22.04container_name: ubuntucap_add:- NET_ADMIN- SYS_ADMIN- SYS_MODULEcommand: "tail -f /dev/null" # 示例&#xff1a;保持容器运行&#xff0c;但不会做任何实际工作#vo…

c++的学习之路:23、多态(2)

摘要 多态的抽象类、原理以及虚表。 目录 摘要 一、抽象类 1、 概念 2、接口继承和实现继承 二、多态的原理 1、虚函数表 2、动态绑定与静态绑定 三、单继承和多继承关系的虚函数表 1、单继承中的虚函数表 2、多继承中的虚函数表 四、思维导图 一、抽象类 1、 概…

LInux shell编程之基础语法

目录 1、shell概述 1.1、查看Linux 提供的 Shell 解析器 1.2、bash 和 sh 的关系 1.3、查看系统&#xff08;centos&#xff09;默认使用的解释器 2、脚本的基础使用 2.1、脚本的格式 2.2、脚本的执行方式 方式一&#xff1a;采用 bash / sh 脚本的相对路径或绝对路径…

java 企业工程管理系统软件源码+Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis

鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 项目背景 一、随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;公司对内部工程管理的…