ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

代码干货——C#Linq表达式按周、旬、季、年聚类投影写法

2021-11-18 09:32:11  阅读:198  来源: 互联网

标签:代码 item Sum Linq 按周 ProdDate 聚类 new GroupBy


转载自:https://blog.csdn.net/qq_37036915/article/details/113728952

 

C#中Linq表达式使用场景(聚类,投影写法) 该项目主要解决石油产量的分析工作,数据库中存了石油产量的日和月数据,其中月数据中包含了年数据的字段和值,因此按日产量、月产量、年产量分析计算不存在什么问题。但项目中需求累计周产量、旬产量、季产量进行分析,这样的需求怎么解决呢? 一般来说有两种解决方案: 将日产量数据获取出来,然后按照日期进行排序,然后对于日产量进行foreach循环,周产量每七天相加可得,但旬产量分为上旬、中旬、下旬,这样对于上旬、中旬来说都是10天,下旬就是每个月的天数减去20天,按照这样的方式进行循环相加,这样做的弊端就是代码不好写且不易控制,代码可读性不佳。笔者并不推荐这种做法,当然大神除外哈。这样就催生了第二种解决方案,使用linq表达式可以很好地将其解决。 使用Linq表达式 假如日数据已经按生产日期进行排序之后获得了日数据list——WellsProdsDay.那么我们首先通过GroupBy()方法进行对周进行分组,代码为: this.WellsProdsDay.GroupBy(x => x.ProdDate.AddDays(-(int)x.ProdDate.DayOfWeek)) prodDate即为每日的生产日期,类型为DateTime类型,于是我们对于周产量的字段写一个bean类,名为WellProdWeekDescriptor,假如这个bean类里定义了周产油量、周产水量(在此只举这两个字段为例)于是可以利用Select方法进行向新表投影,于是代码为:  
var wellsProdsWeek = this.WellsProdsDay.GroupBy(x => x.ProdDate.AddDays(-(int)x.ProdDate.DayOfWeek))
.Select(item => new WellProdWeekDescriptor{ //周产油 WeekOil = item.Sum(y => y.DailyOil), //周产水 WeekWater = item.Sum(y => y.DailyWater)}).ToList();

 

在select方法中提供了Sum()即为求和,Average()方法求平均值,这些可以自己试用,在此只提供Linq写法,最后ToList()方法将新表进行封装,其返回值为List,但为了方便写,C#提供了var替代了具体的返回值。     周分组 同样地,旬产量的分析稍微有一点不同,那就是区分出每个旬的天数,当然一个GroupBy()是不够的,但是我已经写好了获取旬天数的工具方法,在此先展示出旬的工具方法代码:   /// /// 获取指定年,指定月, 指定旬的开始日期 /// /// 年 /// 月 /// 日 /// 日期 public static DateTime GetStartOfTen(int year, int month, int ten) { if (!IsValidYear(year)) { throw new ArgumentOutOfRangeException("Valid values are 0-9999, and your transfer value is" + year); } if (!IsValidMonth(month)) { throw new ArgumentOutOfRangeException("Valid values are 1-12, and your transfer value is" + month); } if (!IsValidTen(ten)) { throw new ArgumentOutOfRangeException("Valid values are 1-3, and your transfer value is" + ten); } if (ten == 1) { return new DateTime(year, month, 1, 0, 0, 0, 0); } else if (ten == 2) { return new DateTime(year, month, 11, 0, 0, 0, 0); } else { return new DateTime(year, month, 21, 0, 0, 0, 0); } }   使用GroupBy()方法对日产量进行分组,代码为: var wellsProdXun = this.WellsProdsDay.GroupBy(x => GetStartOfTen(x.ProdDate)) 其中表达式中调用了GetStartOfTen()方法,根据日期自动分出上旬,中旬、下旬的组别。然后通过Select()方法进行投影,旬产量类名为WellProdXunDescriptor。代码为: var wellsProdXun = this.WellsProdsDay.GroupBy(x => GetStartOfTen(x.ProdDate)).Select(item => new WellProdXunDescriptor{ //旬产油 XunOil = item.Sum(y => y.DailyOil), //旬产水 XunWater = item.Sum(y => y.DailyWater)}).ToList();   旬分组 对于季产量,假如月数据已经按生产日期进行排序之后获得了月数据list——WellMonProdData.那么我们首先通过GroupBy()方法进行对季进行分组,代码为: var wellSeasonProdData = this.WellMonProdData.GroupBy(x => x.ProdDate.AddMonths(0 - (x.ProdDate.Month - 1) % 3).AddDays(1 - x.ProdDate.Day)) 通过Select()方法进行投影,季产量类名为WellProdSeasonDescriptor,代码为: var wellSeasonProdData = this.WellMonProdData.GroupBy(x => x.ProdDate.AddMonths(0 - (x.ProdDate.Month - 1) % 3).AddDays(1 - x.ProdDate.Day)).Select(item => new WellProdSeasonDescriptor{ //季产油 SeasonOil = item.Sum(y => y.MonthlyOil), //季产水 SeasonWater = item.Sum(y => y.MonthlyWater)}).ToList();   季分组 年产量没有直接拿出数据库的字段值,同样也是使用分组的方式,这里把代码附上(原理都一样): var wellYearProdData = this.WellMonProdData.GroupBy(x => x.ProdDate.AddMonths(-(x.ProdDate.Month - 1)).AddDays(1 - x.ProdDate.Day)).Select(item => new WellProdYearDescriptor{ //年产油 YearOil = item.Sum(y => y.MonthlyOil), //年产水 YearWater = item.Sum(y => y.MonthlyWater)}).ToList(); 当然Liuq表达式的强大之处并不局限于此,这只是解决了一个问题的需求,之后有很多地方都用到了Linq表达式的写法,基本很少使用foreach遍历的写法,代码冗长且不易阅读。今天就先分享到这里,接下来还会给大家更新其他的linq表达式以及前端工具包DevExpress的相关用法,如果您点进来请给笔者一个赞或者评论以示鼓励,你们的鼓励是我更新下去的动力。  

标签:代码,item,Sum,Linq,按周,ProdDate,聚类,new,GroupBy
来源: https://www.cnblogs.com/mtpas/p/15570735.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有