OpenAI 和 Stack Overflow 通过 OverflowAPI 访问结合在一起,为 OpenAI 用户和客户提供准确且经过审查的数据基础,AI 工具需要快速找到问题的解决方案,以便技术人员能够专注于优先任务。 OpenAI 还将把来自 Stack Overflow 的经过验证的技术知识直接呈现到 ChatGPT 中,让用户轻松访问可信、归属、准确且高度技术性的知识和代码,这些知识和代码由 15 年来为 Stack Overflow 平台做出贡献的数百万开发人员提供支持。此次合作的一部分:
我不是专家,但是查看 SQL-CLR 类型映射表(例如 http://msdn.microsoft.com/en-us/library/bb386947.aspx),您可以看到 SQL 十进制值已转换转换为 CLR
System.Decimal
类型,并且 CLR System.Decimal
值转换为 SQL DECIMAL(29,4)
类型。
因此,在您的示例中,
a.Weight
作为 SQL 小数转换为 CLR System.Decimal.
a.Weight
除以 a.Count
因此被视为 System.Decimal
除法,并且右操作数 (a.Count
) 必须转换为 CLR System.Decimal.
Linq 然后将此类型转换转换回 SQL,从而导致 Count 转换为 DECIMAL(29,4).
不幸的是,
a.Weight / (double) a.Count
不起作用,因为正确的操作数必须转换为
System.Decimal
,但 double 不能像 int 那样自动转换。然而,
(double) a.Weight / a.Count
会起作用,因为除法现在被视为双精度数除法,而不是
System.Decimals,
,因此生成的 SQL 如下所示:
SELECT (CONVERT(Float,[t0].[Weight])) / (CONVERT(Float,[t0].[Count])) AS [value]
...
您真正想要的是 Linq 将
a.Count
视为小数,而不是整数。您可以通过更改 DBML 文件中 Count 属性的类型来完成此操作(参见此处)。当我这样做时,Linq 查询:
var averageweight = context.AverageWeights
.Where(i => i.ID == 187)
.GroupBy(w => w.ID)
.Select(i => new {Average = i.Average(a => a.Weight/a.Count), Count = i.Count()});
SQL 结果:
SELECT AVG([t0].[Weight] / [t0].[Count]) AS [Average], COUNT(*) AS [Count]
FROM [dbo].[AverageWeight] AS [t0]
WHERE [t0].[ID] = @p0
GROUP BY [t0].[ID]
这就是想要的结果。但是,更改 DBML 文件中 Count 属性的类型可能会产生其他意想不到的副作用。
顺便说一句,从更新的 Linq 查询生成的 SQL 似乎是错误的。 Linq 明确要求所有权重的平均值除以所有计数的平均值,但这不是 SQL 所做的。当我编写相同的 Linq 查询时,我得到的 SQL 是:
SELECT [t1].[value] / (CONVERT(Decimal(29,4),[t1].[value2])) AS [Average], [t1].[value3] AS [Count]
FROM (
SELECT AVG([t0].[Weight]) AS [value], AVG([t0].[Count]) AS [value2], COUNT(*) AS [value3]
FROM [dbo].[Average Weight] AS [t0]
WHERE [t0].[ID] = @p0
GROUP BY [t0].[ID]
) AS [t1]
请注意,对
AVG
的调用有两次,而不是一次。另请注意,到 Decimal(29,4)
的转换仍然存在,因为 Linq 仍在进行 System.Decimal
除法。
我还没有测试过,但你可以尝试投射 a.Count :
... a.Weight / (double) a.Count ...