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

2024-04-12 08:12

本文主要是介绍C# linq 根据多字段动态Group by,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

实现类: 

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 List<Person> Details { get; set; }public override int GetHashCode(){return $"{Name},{Six},{Age}".GetHashCode(); //需要用来分组的字段,或者全部字段}public override bool Equals(object obj){var target = (Person)obj;return this.GetHashCode() == target.GetHashCode();}
}

这篇关于C# linq 根据多字段动态Group by的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/896582

相关文章

springboot如何通过http动态操作xxl-job任务

《springboot如何通过http动态操作xxl-job任务》:本文主要介绍springboot如何通过http动态操作xxl-job任务的问题,具有很好的参考价值,希望对大家有所帮助,如有错... 目录springboot通过http动态操作xxl-job任务一、maven依赖二、配置文件三、xxl-

C#如何去掉文件夹或文件名非法字符

《C#如何去掉文件夹或文件名非法字符》:本文主要介绍C#如何去掉文件夹或文件名非法字符的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#去掉文件夹或文件名非法字符net类库提供了非法字符的数组这里还有个小窍门总结C#去掉文件夹或文件名非法字符实现有输入字

C#之List集合去重复对象的实现方法

《C#之List集合去重复对象的实现方法》:本文主要介绍C#之List集合去重复对象的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C# List集合去重复对象方法1、测试数据2、测试数据3、知识点补充总结C# List集合去重复对象方法1、测试数据

C#实现将Office文档(Word/Excel/PDF/PPT)转为Markdown格式

《C#实现将Office文档(Word/Excel/PDF/PPT)转为Markdown格式》Markdown凭借简洁的语法、优良的可读性,以及对版本控制系统的高度兼容性,逐渐成为最受欢迎的文档格式... 目录为什么要将文档转换为 Markdown 格式使用工具将 Word 文档转换为 Markdown(.

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

MyBatis编写嵌套子查询的动态SQL实践详解

《MyBatis编写嵌套子查询的动态SQL实践详解》在Java生态中,MyBatis作为一款优秀的ORM框架,广泛应用于数据库操作,本文将深入探讨如何在MyBatis中编写嵌套子查询的动态SQL,并结... 目录一、Myhttp://www.chinasem.cnBATis动态SQL的核心优势1. 灵活性与可

C#代码实现解析WTGPS和BD数据

《C#代码实现解析WTGPS和BD数据》在现代的导航与定位应用中,准确解析GPS和北斗(BD)等卫星定位数据至关重要,本文将使用C#语言实现解析WTGPS和BD数据,需要的可以了解下... 目录一、代码结构概览1. 核心解析方法2. 位置信息解析3. 经纬度转换方法4. 日期和时间戳解析5. 辅助方法二、L

Mybatis嵌套子查询动态SQL编写实践

《Mybatis嵌套子查询动态SQL编写实践》:本文主要介绍Mybatis嵌套子查询动态SQL编写方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、实体类1、主类2、子类二、Mapper三、XML四、详解总结前言MyBATis的xml文件编写动态SQL

使用C#删除Excel表格中的重复行数据的代码详解

《使用C#删除Excel表格中的重复行数据的代码详解》重复行是指在Excel表格中完全相同的多行数据,删除这些重复行至关重要,因为它们不仅会干扰数据分析,还可能导致错误的决策和结论,所以本文给大家介绍... 目录简介使用工具C# 删除Excel工作表中的重复行语法工作原理实现代码C# 删除指定Excel单元

SpringBoot实现Kafka动态反序列化的完整代码

《SpringBoot实现Kafka动态反序列化的完整代码》在分布式系统中,Kafka作为高吞吐量的消息队列,常常需要处理来自不同主题(Topic)的异构数据,不同的业务场景可能要求对同一消费者组内的... 目录引言一、问题背景1.1 动态反序列化的需求1.2 常见问题二、动态反序列化的核心方案2.1 ht