EF Core 6:按LotID与MateriauID分组获取最大DateProd记录
EF Core 获取每个LotID-MateriauID组合的最新重量记录
我是EF Core初学者,现有一张Prod表,每当产品重量发生变化时就会插入新行。我需要获取每个LotID-MateriauID组合下,DateProd最大的那条记录(即最新重量数据)。
我的模型定义如下:
public class Prod { [Required] public int ProdID { get; set; } // 主键 public int LotID { get; set; } public int MateriauID { get; set; } public float? Weight{ get; set; } public DateTime? DateProd { get; set; } public Lot? Lot { get; set; } public Materiau? Materiau { get; set; } }
比如我需要获取LotID与MateriauID对应组合中DateProd最大的数据(如示例中的第3行)。我尝试了以下代码,但未能实现需求:
var prod = _context.Prods.Include(x => x.Materiau) .Include(y => y.Lot) .Where(b => b.LotID == LotID); var prodMax = prod.GroupBy(x => x.LotID, x=>x.MateriauID) .Select(s => s.OrderByDescending(x => x.dateProd).First()) .ToListAsync();
问题分析
原来的代码存在两个关键问题:
GroupBy(x => x.LotID, x=>x.MateriauID)仅按LotID分组,且只保留MateriauID作为组内元素,丢失了Prod实体的其他字段,无法获取完整记录。- 代码中
x.dateProd为小写,与模型里的DateProd属性名不匹配,会导致编译错误。
解决方案
要实现按LotID-MateriauID组合分组并取每组最新记录,有两种常用方案:
方式一:组合键分组
直接将LotID和MateriauID作为组合分组键,在每个组内按DateProd降序排序后取第一条:
var prodMax = await _context.Prods .Include(x => x.Materiau) .Include(x => x.Lot) .Where(b => b.LotID == LotID) .GroupBy(x => new { x.LotID, x.MateriauID }) .Select(g => g.OrderByDescending(x => x.DateProd).FirstOrDefault()) .ToListAsync();
方式二:子查询关联(大数据量更优)
先查询每个LotID-MateriauID组合的最大DateProd,再关联主表获取对应完整记录:
var latestDates = _context.Prods .Where(b => b.LotID == LotID) .GroupBy(x => new { x.LotID, x.MateriauID }) .Select(g => new { g.Key.LotID, g.Key.MateriauID, MaxDate = g.Max(x => x.DateProd) }); var prodMax = await _context.Prods .Include(x => x.Materiau) .Include(x => x.Lot) .Join(latestDates, prod => new { prod.LotID, prod.MateriauID, prod.DateProd }, latest => new { latest.LotID, latest.MateriauID, latest.MaxDate }, (prod, latest) => prod) .ToListAsync();
两种方式都能正确获取目标数据,可根据实际数据量选择合适方案。
内容的提问来源于stack exchange,提问作者Maysa
相关产品推荐
相关产品推荐

