【问题标题】:Get the row with the max(DateTime) LINQ [duplicate]获取具有 max(DateTime) LINQ 的行 [重复]
【发布时间】:2021-04-28 13:10:32
【问题描述】:

Message 表中的每一行都包含一个 DateTime。如何获取具有最高 DateTime(最新日期)的消息行?

我现在有了这个:

public async Task<IEnumerable<Message>> getLastMessageByUnit(int unitId)
{
    IQueryable<Message> tempQuery = context.Message;
    tempQuery = tempQuery.Where((x) => x.Unit == unitId);

    return await tempQuery.ToListAsync();
}

但是当我这样做时:

public async Task<IEnumerable<Message>> getLastMessageByUnit(int unitId)
{
    IQueryable<Message> tempQuery = context.Message;
    tempQuery = tempQuery.Where((x) => x.Unit == unitId).Max(x => x.DateTime);

    return await tempQuery.ToListAsync();
}

我收到以下错误:

严重性代码描述项目文件行抑制状态 错误 CS0029 无法将类型“System.DateTime”隐式转换为“System.Linq.IQueryable

【问题讨论】:

  • OderByDescending+First
  • 你将如何在 SQL 中做到这一点?同样的方式适用于 LINQ
  • 你应该返回Task&lt;Message&gt;而不是Task&lt;IEnumerable&lt;Message&gt;&gt;,因为只有一个项目。

标签: c# linq


【解决方案1】:

按日期排序并取第一个

public async Task<Message> GetLastMessageByUnit(int unitId)
{
  return await context.Message
    .Where(x => x.Unit == unitId)
    .OrderByDescending(x => x.DateTime)
    .FirstOrDefaultAsync();
}  

..如果你真的需要它在一个列表中,将它添加到一个列表中(但我会更改方法的返回类型),因为正如 Johnathan Barclay 在 cmets 中指出的那样,它不会将方法命名为返回一个项目但让它返回多个项目的意义

您不能使用 Max,因为它只会返回最高的日期时间(并丢弃其余信息),类似于 SELECT MAX(datetime) FROM t WHERE UnitId = 123 的方式。您正在寻找的是与SELECT TOP 1 * FROM t WHERE UnitID = 123 ORDER BY DateTime DESC 等效的LINQ。

MoreLinq 库有一个 MaxBy 扩展,它可以做类似的事情,但你应该注意它的功能是否可以在 SQL 中翻译。例如,如果你正在处理本地数据,MaxBy 可能提供有用的性能提升,因为没有必要仅对数据负载进行排序以获取一个项目,当“在其上循环跟踪您看到的最高 X 及其相关 Y”就足够了

【讨论】:

  • 是的,MaxBy 不适用于 IQueryable
猜你喜欢
  • 2012-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多