Linq中GroupBy与OrderBy结合Select new指定返回字段的方法
问题背景
需求为从订单数据集中,返回每个OrderId对应Status数值最小的唯一行,结果示例:
当前可正常运行、但会返回全表字段的查询代码如下:
var result = _dbContext.Orders .GroupBy(s => s.OrderId) .Select(group => group.OrderBy(x => x.Status).First()).ToList();
需要修改上述查询,仅返回OrderId、Status、Date三个指定字段,避免查询全表数十个冗余字段,已知需使用匿名类型投影语法,但无法正确整合到现有查询逻辑中。
实现方案
直接在分组查询逻辑中嵌入字段投影即可,EF会自动将投影逻辑翻译成SQL的SELECT子句,仅查询指定字段,不会拉取全量列数据。以下两种写法均可正常运行:
- 写法1(拆分投影逻辑,适配所有EF版本,部分老版本EF可能生成冗余字段查询)
var result = _dbContext.Orders .GroupBy(s => s.OrderId) // 先取每个分组下Status最小的行 .Select(group => group.OrderBy(x => x.Status).First()) // 再投影需要的三个字段 .Select(targetRow => new { targetRow.OrderId, targetRow.Status, targetRow.Date }) .ToList();
- 写法2(分组内直接投影,推荐,所有版本EF均可生成最高效SQL,仅查询三个字段)
var result = _dbContext.Orders .GroupBy(s => s.OrderId) .Select(group => group .OrderBy(x => x.Status) // 排序后直接投影需要的字段,再取第一条 .Select(x => new { x.OrderId, x.Status, x.Date }) .First() ) .ToList();
提示:如果使用EF Core 6及以上版本,两种写法经过EF的查询优化后会生成完全一致的高效SQL,不存在性能差异;如果使用老版本EF/EF Core,优先选择第二种写法避免全字段查询。
内容的提问来源于stack exchange,提问作者PixelPaul
相关产品推荐
相关产品推荐

