有個需求是要根據多個字段動態進行分組,具體效果如下
平常一般用的都是根據具體的字段的取進行分組的,百度一下發現已有解決方案。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多條件動態分組了。