使用EntityFramework查询异常:日/月/年Scrap报表数据不一致
问题分析与解决方案
问题原因
1. 图表数据处理逻辑错误(核心问题)
你在生成图表的y轴数据时,错误使用了DistinctBy(x => x.Quantity),这会过滤掉所有Quantity值重复的记录,只保留不同Quantity值的条目。比如日报表的126条记录中,可能只有32个不同的Quantity数值,因此月/年报表最终显示的是去重后的32个值,而非实际的总Scrap数量或按生产线(Line)分组的统计量。
同时,x轴数据按Line去重,y轴数据按Quantity去重,两者没有对应关系,完全不符合“按生产线统计Scrap数量”的需求。
2. 查询函数的潜在问题
- 多次调用
DateTime.Now:查询执行过程中如果跨了时间节点(比如午夜),会导致筛选条件不一致; - 直接对
Created的Year/Month/Day属性筛选:EF可能无法为该条件生成高效的SQL,导致全表扫描,影响查询性能。
修复方案
1. 修正图表数据处理逻辑
将按Line分组并计算每个生产线的总Scrap数量,替换原来的去重逻辑:
//Daily Bar Chart SCRAP List<Scrap> dailyScrap = await _scrapService.GetDailyScrap(); var dailyScrapGrouped = dailyScrap .GroupBy(scrap => scrap.Line) .Select(group => new { Line = group.Key, TotalQuantity = group.Sum(scrap => scrap.Quantity) }) .ToList(); List<string> xValues = dailyScrapGrouped.Select(g => g.Line).ToList(); List<int> yValues = dailyScrapGrouped.Select(g => g.TotalQuantity).ToList(); // Monthly Bar Chart SCRAP List<Scrap> monthlyScrap = await _scrapService.GetMonthlyScrap(); var monthlyScrapGrouped = monthlyScrap .GroupBy(scrap => scrap.Line) .Select(group => new { Line = group.Key, TotalQuantity = group.Sum(scrap => scrap.Quantity) }) .ToList(); List<string> xValuesMonthly = monthlyScrapGrouped.Select(g => g.Line).ToList(); List<int> yValuesMonthly = monthlyScrapGrouped.Select(g => g.TotalQuantity).ToList(); // Year Bar Chart SCRAP List<Scrap> yearScrap = await _scrapService.GetYearScrap(); var yearScrapGrouped = yearScrap .GroupBy(scrap => scrap.Line) .Select(group => new { Line = group.Key, TotalQuantity = group.Sum(scrap => scrap.Quantity) }) .ToList(); List<string> xValuesYear = yearScrapGrouped.Select(g => g.Line).ToList(); List<int> yValuesYear= yearScrapGrouped.Select(g => g.TotalQuantity).ToList();
2. 优化查询函数的时间筛选逻辑
使用时间范围查询替代直接判断Year/Month/Day,同时缓存当前时间避免多次调用的问题:
public async Task<List<Scrap>> GetDailyScrap() { var today = DateTime.Today; var tomorrow = today.AddDays(1); return await _dbContext.Scrap .Where(x => x.Created >= today && x.Created < tomorrow) .ToListAsync(); } public async Task<List<Scrap>> GetMonthlyScrap() { var now = DateTime.Now; var startOfMonth = new DateTime(now.Year, now.Month, 1); var startOfNextMonth = startOfMonth.AddMonths(1); return await _dbContext.Scrap .Where(x => x.Created >= startOfMonth && x.Created < startOfNextMonth) .ToListAsync(); } public async Task<List<Scrap>> GetYearScrap() { var now = DateTime.Now; var startOfYear = new DateTime(now.Year, 1, 1); var startOfNextYear = startOfYear.AddYears(1); return await _dbContext.Scrap .Where(x => x.Created >= startOfYear && x.Created < startOfNextYear) .ToListAsync(); }
效果说明
修正后,月/年报表会正确按生产线统计Scrap总数量,KST-420的Scrap数据也会在对应报表中正常显示;同时查询性能也会因使用范围筛选而得到提升。
内容的提问来源于stack exchange,提问作者Lora
相关产品推荐
相关产品推荐

