使用LINQ的Take(1)时如何获取多列数据?
问题
我有一张存储训练统计数据的表,包含BroadJumpFeet(英尺)和BroadJumpInches(英寸)字段。我通过以下LINQ语句获取最远跳远记录:
var playerBroadJumpHistory = await api.GetAllWorkOutsByPlayerId(playerId); var maxBroadJumpFeet = (from u in playerBroadJumpHistory where u.PlayerId == playerId orderby u.BroadJumpFeet descending select u).Take(1);
但我同时需要获取BroadJumpInches的值,如何在保留这两个数据的前提下实现?我需要这两列数据用于展示最远跳远距离,是否可以通过select创建新对象来实现?
解决方案
完全可以通过select创建新对象来获取目标字段,同时还要优化排序逻辑——如果存在多条记录英尺数相同的情况,必须按英寸倒序才能拿到真正的最远记录。
方法一:使用匿名对象
直接在select中指定需要的字段,生成匿名对象,适合仅当前场景使用的情况:
var playerBroadJumpHistory = await api.GetAllWorkOutsByPlayerId(playerId); var maxBroadJump = (from u in playerBroadJumpHistory where u.PlayerId == playerId // 先按英尺倒序,英尺相同则按英寸倒序 orderby u.BroadJumpFeet descending, u.BroadJumpInches descending select new { u.BroadJumpFeet, u.BroadJumpInches }).FirstOrDefault();
用FirstOrDefault()替代Take(1)更实用,它直接返回单个对象(而非集合),方便后续取值。
方法二:自定义实体类(复用场景)
如果这个数据结构需要在多个业务场景中使用,可以定义一个专门的实体类:
public class BroadJumpRecord { public int BroadJumpFeet { get; set; } public int BroadJumpInches { get; set; } }
然后在LINQ查询中返回该类的实例:
var maxBroadJump = (from u in playerBroadJumpHistory where u.PlayerId == playerId orderby u.BroadJumpFeet descending, u.BroadJumpInches descending select new BroadJumpRecord { BroadJumpFeet = u.BroadJumpFeet, BroadJumpInches = u.BroadJumpInches }).FirstOrDefault();
额外优化
由于api.GetAllWorkOutsByPlayerId(playerId)已经是按玩家ID筛选后的数据集,LINQ中的where u.PlayerId == playerId可以省略,同时用方法链写法让代码更简洁:
var playerBroadJumpHistory = await api.GetAllWorkOutsByPlayerId(playerId); var maxBroadJump = playerBroadJumpHistory .OrderByDescending(u => u.BroadJumpFeet) .ThenByDescending(u => u.BroadJumpInches) .Select(u => new { u.BroadJumpFeet, u.BroadJumpInches }) .FirstOrDefault();
内容的提问来源于stack exchange,提问作者dotnetdevcsharp
相关产品推荐
相关产品推荐

