C# Max(x=>;x.Time)与OrderByDescending(x=>;x.Time).First().Time
我提出了一个相关问题:C# Max(x=>;x.Time)与OrderByDescending(x=>;x.Time).First().Time,c#,linq,linqpad,sqlexception,C#,Linq,Linqpad,Sqlexception,我提出了一个相关问题: 我正试图按照这里的要求获得小组的第一行: 但是,我使用Max来处理它与公认的答案不同。我是这样做的: ATable .GroupBy (t => t.ID) .Select ( t => t.OrderByDescending(x=>x.Timestamp).FirstOrDefault().Timestamp) 这将导致错误SqlException:无效的列名“ID” 现在,当我使用Max函数时: ATable .Grou
我正试图按照这里的要求获得小组的第一行:
但是,我使用Max来处理它与公认的答案不同。我是这样做的:
ATable
.GroupBy (t => t.ID)
.Select ( t => t.OrderByDescending(x=>x.Timestamp).FirstOrDefault().Timestamp)
这将导致错误SqlException:无效的列名“ID”
现在,当我使用Max函数时:
ATable
.GroupBy (t => t.ID)
.Select ( t => t.Max(x=>x.Timestamp))
它返回我想要的时间列表
我的理解是,他们是不同的,但相当于电话。为什么在第一次调用时出现sql错误
更新为第一个查询生成的sql查询如下所示:
SELECT (
SELECT [t3].[Timestamp]
FROM (
SELECT TOP 1 [t2].[Timestamp]
FROM [ATable] AS [t2]
WHERE (([t1].[ID] IS NULL) AND ([t2].[ID] IS NULL)) OR (([t1].[ID] IS NOT NULL) AND ([t2].[ID] IS NOT NULL) AND ([t1].[ID] = [t2].[ID]))
ORDER BY [t2].[Timestamp] DESC
) AS [t3]
) AS [value]
FROM (
SELECT [t0].[ID]
FROM [ATable] AS [t0]
GROUP BY [t0].[ID]
) AS [t1]
我设法减少了它,但保留了相同的错误:
SELECT (
SELECT [t3].[Timestamp]
FROM (
SELECT TOP 1 [Timestamp]
FROM [ATable]
WHERE [t1].[ID] = [ID]
) AS [t3]
) AS [value]
FROM (
SELECT [ID]
FROM [ATable]
GROUP BY [ID]
) AS [t1]
更新2一些回答说,这些查询在逻辑上是不同的,但是,如果在northwind表上执行类似操作,将产生相同的结果:
OrderDetails
.GroupBy(x=>x.ProductID)
.Select(x=>x.OrderByDescending(y=>y.UnitPrice).FirstOrDefault().UnitPrice).Dump();
OrderDetails
.GroupBy(x=>x.ProductID)
.Select(x=>x.Max(y=>y.UnitPrice)).Dump();
因此,我不能接受以下三种回答中的任何一种,即查询不同,或者Max给出的是一个总和而不是列表的最大值,或者在继续之前必须将iQuery转换为列表。更新2:我只想回答以下问题: 然而,如果你这样做 在northwind桌上,它会 产生相同的结果[…]所以我 无法接受3个答案中的任何一个 也就是说,查询是不同的 我并不是要反驳他们应该产生同样的结果。为了更好地说明我的观点,让我提供一个类比 假设我给你一堆从1到50的索引卡,然后我说,“把这些都整理好。”所以,你把它们整理好,确保这一堆从1到50。这需要你一两分钟。然后我说,“现在把那张牌给我。”这张牌正好是50号的牌 另一方面,假设我首先说的是,“给我这堆牌中数字最高的那张牌。”然后你所要做的就是仔细检查这些牌,找到数字最高的那张牌,而不需要做任何排序。(我的意思是,你可以先对堆进行排序,但这显然比我要求的要多。) 所以我想说的是,上述两组指令的结果是相同的;然而,它们显然是不同的指示 现在,如果某些实现足够智能,能够将它们转换为相同的(优化的)SQL查询,我一点也不会感到惊讶;我想说的是,由于它们是不同的指令,因此如果生成的SQL是不同的,也就不太奇怪了(尽管这可能是不幸的,但是一个版本可能会导致错误,而另一个版本则不会)
更新:再一次,我不能给出关于Linq到SQL的详细回复;但我要指出的是,虽然理论上,
Max
应该与OrderByDescending
和firstorderdefault
产生相同的结果,但从概念的角度来看,它实际上并不相同
考虑Linq到对象。调用Max
将迭代序列并累积最大值。调用OrderByDescending
将对整个序列进行排序,然后取顶部
显然,Linq到SQL是另一种动物;但是,由于这些查询在概念上代表了获得特定结果的不同方法,因此它们生成的SQL很可能是(而且正如您所看到的)不同的
原始答案 我不能就Linq到SQL给出详细的回答,但我要指出的是,您的两个备选方案之间存在着非常严重的差异(它们不是等价的): 上面应该返回最大的时间戳 上面应该返回具有最大时间戳的记录
这些是非常不同的野兽。本质上,两者都是相同的,但他可以简单地链接
。Timestamp
在调用FirstOrDefault
后,问题应该是将表达式树转换为sql语句。我的错,我实际上是链接。Timestamp
来获取错误,仅仅获取FirstOrDefault()并不会给出错误。现在更新问题。@Femaref:他能做到(也许他做到了);我只是想我应该指出这一点,以防OP对Max
的功能有错误的印象(我知道我犯了一个错误,认为它会多次返回Max的记录)。@Joe:谢谢你澄清这一点。我还有一个额外的观察;那我就上路了……是的,我有时也会爱上它。需要MaxBy
运算符。您能为第一个查询找到生成的SQL查询吗?服务器日志应该有它们。作为对所提供答案的响应,如果您遵循第二个链接,则提供了一个解决方案(不接受),该解决方案使用OrderByDescending,但不链接.Timestamp或一般。[FieldID]。这就返回了第一行。。但是链接字段不起作用(即使使用FirstOrDefault)。如果它在没有链接时间戳的情况下工作,那么两个查询之间肯定有很大的区别。
Max(x => x.Timestamp)
OrderByDescending(x => x.Timestamp()).FirstOrDefault()