Linq 动态多条件group by

有个需求是要根据多个字段动态进行分组,具体效果如下

 平常一般用的都是根据具体的字段的取进行分组的,百度一下发现已有解决方案。https://www.cnblogs.com/devindong/p/3615625.html

第一种是直接用动态拼接分组条件,缺点在于如果是多个分组条件的话,分组条件将变得非常难写,也很难写全

private static dynamic GroupBy(dynamic r)
        {
            int a = 1, b = 2;

            if (a < b) return new { id = r.id};

            else if (a == b) return new { name=rd.name };

            else return new { a = r.a };
        }

还有一种是可以创建一个结构体来解决。需要注意的是,如果不用结构体而是选择class的话需要重写类的GetHashCode方法来重写类的相等判断方法。

该功能中构建的结构体为,根据相应的name group是为了拿key的时候取到对应的名称

public struct MassPatternDesignGroup
    {
        /// <summary>
        ///     波段Id
        /// </summary>
        public Guid? BandId { get; set; }

        /// <summary>
        ///     波段名称
        /// </summary>
        public string BandName { get; set; }

        /// <summary>
        ///     设计师Id
        /// </summary>
        public Guid? DesignerId { get; set; }

        /// <summary>
        ///     设计师
        /// </summary>
        public string DesignerName { get; set; }

        /// <summary>
        ///     品类Id
        /// </summary>
        public Guid? ProductCategoryId { get; set; }

        /// <summary>
        ///     品类名称
        /// </summary>
        public string ProductCategoryName { get; set; }

        /// <summary>
        ///     主题Id
        /// </summary>
        public Guid? ThemePlanId { get; set; }

        /// <summary>
        ///     主题名称
        /// </summary>
        public string ThemePlanName { get; set; }

        /// <summary>
        ///     系列Id
        /// </summary>
        public Guid? ProductSeriesId { get; set; }

        /// <summary>
        ///     系列名称
        /// </summary>
        public string ProductSeriesName { get; set; }

        /// <summary>
        ///     廓形Id
        /// </summary>
        public Guid? SilhouetteId { get; set; }

        /// <summary>
        ///     廓形名称
        /// </summary>
        public string SilhouetteName { get; set; }

        /// <summary>
        ///     款式来源Id
        /// </summary>
        public Guid? PatternPropertyId { get; set; }

        /// <summary>
        ///      款式来源名称
        /// </summary>
        public string PatternPropertyName { get; set; }

        /// <summary>
        ///     销售渠道Id
        /// </summary>
        public Guid? SalesChannelsId { get; set; }

        /// <summary>
        ///     销售渠道名称
        /// </summary>
        public string SalesChannelsName { get; set; }

        public string GetKey()
        {
            return
                $"{BandName} {DesignerName} {ProductCategoryName} {ThemePlanName} {ProductSeriesName} {SilhouetteName} {PatternPropertyName} {SalesChannelsName}";
        }
    }

其中GetKey方法为获取分组条件。

group的model类为

public class MassPatternDesignGroupModel
    {
        /// <summary>
        /// 波段
        /// </summary>
        public bool Band { get; set; }

        /// <summary>
        /// 设计师
        /// </summary>
        public bool Designer { get; set; }

        /// <summary>
        /// 品类
        /// </summary>
        public bool ProductCategory { get; set; }

        /// <summary>
        ///  主题
        /// </summary>
        public bool ThemePlan { get; set; }

        /// <summary>
        /// 系列
        /// </summary>
        public bool ProductSeries { get; set; }

        /// <summary>
        /// 廓形
        /// </summary>
        public bool Silhouette { get; set; }

        /// <summary>
        /// 款式来源
        /// </summary>
        public bool PatternProperty { get; set; }

        /// <summary>
        /// 销售渠道
        /// </summary>
        public bool SalesChannels { get; set; }

        /// <summary>
        ///     品牌Id
        /// </summary>
        public Guid BrandId { get; set; }

        /// <summary>
        ///     年份
        /// </summary>
        public int Year { get; set; }

        /// <summary>
        ///     季节Id
        /// </summary>
        public Guid SeasonId { get; set; }

        /// <summary>
        ///     机构Id
        /// </summary>
        public Guid OrganizationId { get; set; }

        public MassPatternDesignGroup GroupBy(dynamic r)
        {
            var g = new MassPatternDesignGroup();
            if (Band)
            {
                g.BandId=r.BandId;
                g.BandName=r.BandName;
            }

            if (Designer)
            {
                g.DesignerId = r.DesignerId;
                g.DesignerName = r.DesignerName;
            }

            if (ProductCategory)
            {
                g.ProductCategoryId = r.ProductCategoryId;
                g.ProductCategoryName = r.ProductCategoryName;
            }

            if (ThemePlan)
            {
                g.ThemePlanId = r.ThemePlanId;
                g.ThemePlanName = r.ThemePlanName;
            }

            if (ProductSeries)
            {
                g.ProductSeriesId = r.ProductSeriesId;
                g.ProductSeriesName = r.ProductSeriesName;
            }

            if (Silhouette)
            {
                g.SilhouetteId = r.SilhouetteId;
                g.SilhouetteName = r.SilhouetteName;
            }

            if (PatternProperty)
            {
                g.PatternPropertyId = r.PatternPropertyId;
                g.PatternPropertyName = r.PatternPropertyName;
            }

            if (SalesChannels)
            {
                g.SalesChannelsId = r.SalesChannelsId;
                g.SalesChannelsName = r.SalesChannelsName;
            }

            return g;
        }

     
    }

其中的字段是前台传过来的分组项,分组时通过MassPatternDesignGroupModel调用GroupBy方法进行动态的多条件分组。

具体的调用如下

public ActionResult GetList(MassPatternDesignGroupModel model)
        {
            var result = new List<MassPatternDesignGroupQueryPanelDto>();
            var massPatternDesignGroups = _designGroupQueryService.GetMassPatternDesignGroupQueryList(model.BrandId, model.Year, model.SeasonId, model.OrganizationId);
            var list= massPatternDesignGroups.GroupBy(a => model.GroupBy(a)).ToList();//动态分组
            list.ForEach(a =>
            {
                var dto=new MassPatternDesignGroupQueryPanelDto()
                {
                    Title = a.Key.GetKey(),
                    Items = a.OrderBy(b=>b.UUID).ToList()
                };
                dto.TaskCount = dto.Items.Count(b => b.Type == MassPatternDesignGroupQueryType.任务);
                dto.DesignCount = dto.Items.Count(b => b.Type == MassPatternDesignGroupQueryType.设计);
                dto.ProofCount = dto.Items.Count(b => b.Type == MassPatternDesignGroupQueryType.打样);
                dto.MassCount = dto.Items.Count(b => b.Type == MassPatternDesignGroupQueryType.选款);

                result.Add(dto);
            });
            return this.Direct(result);
        }

 以上,就实现了Linq to Object多条件动态分组了。

原文地址:https://www.cnblogs.com/Cyril-hcj/p/12956476.html