如何用LINQ编写按districtid和月份分组统计的查询(ASP.NET Core+EF Core)
把MySQL分组统计查询转成EF Core LINQ的解决方案
嘿,恭喜你搞定第一个基于ASP.NET Core和EF Core的C#应用!针对你要转换的MySQL分组统计查询,我来帮你写出正确的LINQ代码,顺便梳理下你之前代码里的小问题~
首先先明确原SQL的逻辑:按districtid和registerDate的月份分组,统计每个分组下的记录数,最终返回districtid、记录数量、月份这三个字段。
方法链风格的LINQ写法(和你之前尝试的写法风格一致)
var streetCrimeStats = this.database.StreetCrimes // 按districtid和注册日期的月份进行分组,用匿名类型包装两个分组键 .GroupBy(s => new { s.districtid, Month = EF.Functions.DatePart("month", s.registerDate) }) // 从分组结果中提取需要的字段 .Select(g => new { DistrictId = g.Key.districtid, CrimeCount = g.Count(), // 对应SQL的COUNT(id),因为id非空时Count()和COUNT(id)效果一致 g.Key.Month }) .ToList(); // 执行查询并转为列表
查询语句风格的LINQ写法(更接近SQL的结构,可读性更强)
var streetCrimeStats = from crime in this.database.StreetCrimes group crime by new { crime.districtid, Month = EF.Functions.DatePart("month", crime.registerDate) } into crimeGroup select new { DistrictId = crimeGroup.Key.districtid, CrimeCount = crimeGroup.Count(), crimeGroup.Key.Month };
一些关键说明
- 你之前的代码顺序有误:应该先分组,再统计,而不是先Select、Count再GroupBy,顺序错了会导致逻辑偏离预期。
- 关于月份的获取:用
EF.Functions.DatePart("month", s.registerDate)是EF Core中对应MySQLMONTH()函数的标准写法,能确保EF Core正确生成对应的SQL语句。如果你的EF Core版本较新,也可以直接用s.registerDate.Month,不过要注意数据库和应用的时区一致性,避免时间转换出错。 - 统计数量时,
g.Count()等同于SQL里的COUNT(id),因为只要记录存在,id(主键)必然非空,所以直接统计分组内的记录数即可。
内容的提问来源于stack exchange,提问作者Debreker
相关产品推荐
相关产品推荐

