首页 > 编程语言 >C#根据传入的字段名,动态分组,支持多字段分组

C#根据传入的字段名,动态分组,支持多字段分组

时间:2024-08-15 16:09:23浏览次数:13  
标签:return C# public item 分组 var Expression 多字段

 

分组方法DynamicLinqExtensions:

/// <summary>
/// 动态构建分组表达式
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="propertyNames">上限最大7个元素</param>
/// <returns></returns>
public static Expression<Func<T, object>> GroupByExpression<T>(string[] propertyNames)
{
    var properties = propertyNames.Select(name => typeof(T).GetProperty(name)).ToArray();
    var propertyTypes = properties.Select(p => p.PropertyType).ToArray();
    var tupleTypeDefinition = typeof(Tuple).Assembly.GetType("System.Tuple`" + properties.Length);
    var tupleType = tupleTypeDefinition.MakeGenericType(propertyTypes);
    var constructor = tupleType.GetConstructor(propertyTypes);
    var param = Expression.Parameter(typeof(T), "item");
    var body = Expression.New(constructor, properties.Select(p => Expression.Property(param, p)));
    var expr = Expression.Lambda<Func<T, object>>(body, param);
    return expr;
}

/// <summary>
/// 动态分组
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="propertyNames">任意个数元素</param>
/// <returns></returns>
public static IEnumerable<IGrouping<object[], T>> GroupByDynamic<T>(this IEnumerable<T> source, params string[] propertyNames)
{
    var parameter = Expression.Parameter(typeof(T), "item");
    var projections = propertyNames.Select(propertyName =>
        Expression.PropertyOrField(parameter, propertyName)
    ).ToArray();

    var body = Expression.NewArrayInit(typeof(object), projections.Cast<Expression>());
    var lambda = Expression.Lambda<Func<T, object[]>>(body, parameter);

    return source.GroupBy(lambda.Compile(), new ObjectArrayComparer());
}

 

// 自定义比较器,用于比较object数组  
public class ObjectArrayComparer : IEqualityComparer<object[]>
{
    public bool Equals(object[] x, object[] y)
    {
        if (x == null && y == null) return true;
        if (x == null || y == null) return false;
        if (x.Length != y.Length) return false;

        for (int i = 0; i < x.Length; i++)
        {
            if (!Equals(x[i], y[i])) return false;
        }

        return true;
    }

    public int GetHashCode(object[] obj)
    {
        unchecked
        {
            int hash = 17;
            foreach (var item in obj)
            {
                if (item != null)
                {
                    hash = hash * 23 + item.GetHashCode();
                }
            }
            return hash;
        }
    }
}
View Code

 

标签:return,C#,public,item,分组,var,Expression,多字段
From: https://www.cnblogs.com/SmilePastaLi/p/18361147

相关文章

  • WPF Customize control
    //xaml<UserControlx:Class="WpfApp246.EllipseTbk"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc=&q......
  • SpringBoot修改内置tomcat版本的操作步骤
    一:由于Tomcat高危漏洞影响,本文介绍了如何查询和修改Springboot内嵌的Tomcat版本,包括通过POM文件或mvnrepository查询版本,以及通过添加properties配置更改版本。此外,还提到了遇到缺少tomcat-juli依赖时的解决办法。最近Tomcat爆出高危漏洞,基本影响所有的Tomcat版本,故需要对sprin......
  • 使用dotenv保护JavaScript代码中的秘密信息
    把诸如apikey这种秘密信息写死的源代码里不可取,比如通常源代码会通过git仓库等进行管理,这样敏感信息就会被共享了。我们选择使用dotenv库把敏感信息配置在.env文件中,然后把.env文件添加到gitignore文件里,不上传到代码仓库。node程序启动后,会将.env文件里的配置项加载到进程对应......
  • 机器学习-卷积神经网络(CNN)
    机器学习-卷积神经网络(CNN)1.卷积神经网络的基本概念1.1卷积层(ConvolutionalLayer)1.1.1卷积操作1.1.2特征图(FeatureMap)1.2激活函数(ActivationFunction)1.2.1ReLU(RectifiedLinearUnit)1.2.2其他激活函数1.3池化层(PoolingLayer)1.3.1最大池化(MaxPooling)1.3.2......
  • GridViewComboBoxColumn设置DataTypeConverter
    GridView中的GridViewComboBoxColumn列,如果需要使用TypeConverter将非字符串类型的数据源转换为字符串进行展示,可按如下几步进行:例如,数据源为如下枚举类型:publicenumMyColor{Red,Yellow,Green}展示的时候,需要转换为汉字,先定义如下类型,作为GridViewComboBo......
  • 【cmake】关于cmake链接库的顺序要求
    注意注意:在CMake中,你可以使用target_link_libraries命令来指定链接顺序。这个命令接受一个目标(target)和一系列库(库可以是库目标、库文件路径或导入的库目标)作为参数。链接顺序通常很重要,特别是当库之间存在依赖关系时。cmake_minimum_required(VERSION3.10)project(My......
  • CF1988D The Omnipotent Monster Killer
    luogu中文题面:https://www.luogu.com.cn/problem/CF1988D树形dp。我们只关心子树的根节点v什么时候被删去。dp[u][i]+=min(dp[v][1...i-1,i+1...T]).T是log(n)的。因为\(T\leqMex(u)\),而考虑要多少节点使\(Mex(u)=T\),有\(f_T=1+f_1+...f_{T-1}\)得\(T=log_2n\)不......
  • 解决 Docker CE 在无根模式(rootless)下无法通过 IPv6 拉取映像的问题
    折腾一天快把我逼疯了本来Docker对IPv6的支持就不好,再来个rootless,雪上加霜首先,我们要区分DockerEngine和里面的Image。拉取映像是DockerEngine在工作,也就是那个Daemon本身,而不是某个container或image。RootlessDocker使用RootlessKit来管理用户命名......
  • 基于价值流DevSecOps效能案例介绍
    背景    数字经济时代,企业数字化转型加速,软件业务收入目标设定,产业基础保障水平提升。DevSecOps:作为解决交付能力挑战的方法,强调开发(Dev)、安全(Sec)、运维(Ops)的整合。DevSecOps持续发布流水线通过两种发布快速通路实现质量效率的均衡,一种是以自动Q点(质量检查点)检查快速上线方......
  • Windows11 微软Microsoft官方系统安装、重装操作教程
    01系统镜像下载推荐到微软中国官网下载Windows正版系统,或者可以到第三方的系统镜像下载站获取下载链接,使用迅雷工具进行下载,我这里推荐两个下载站,如果不想弄迅雷下载那么麻烦,也可以用我的123盘分享下载还是那句话,非常不建议下载各种奇葩定制系统,大部分系统中有夹带私货,安全性和......