【发布时间】:2021-04-13 01:16:11
【问题描述】:
我正在努力解决一个错误,该错误影响了我们用于客户洞察的系统。代码如下:
Insights MyInsights = new Insights();
MyInsights.UnpostedInvoiceValue = DatabaseContext.Invoice
.Where(z => z.OwnedBy.TenantId == CurrentTenant.TenantId && z.Posted == false)
.Sum(x => x.Items.Sum(y =>(y.PricePerUnit / y.ExchangeRate) * y.Quantity / y.Units.PriceFactor));
问题在于“.ExchangeRate”或“y.Units.PriceFactor”为 0(零)时,因为我们不可能全部除以零,所以我们得到了一个例外。
由于该系统是多租户的,这似乎会影响所有租户,即使只有一个租户的数据中有 0(零)。我原以为情况并非如此,因为我们有一个 Where 子句可以检查租户 ID。
生成的SQL如下:
SELECT (
SELECT SUM((([y].[PricePerUnit] / [y].[ExchangeRate]) * [y].[Quantity]) / [y.Units].[PriceFactor])
FROM [InvoiceItem] AS [y]
LEFT JOIN [Units] AS [y.Units] ON [y].[UnitsId] = [y.Units].[UnitsId]
WHERE [z].[InvoiceId] = [y].[InvoiceId]
)
FROM [Invoice] AS [z]
WHERE ([z].[OwnedByTenantId] = @__CurrentTenant_TenantId_0) AND ([z].[Posted] = 0)
返回的异常是:
System.Data.SqlClient.SqlException: 'Divide by zero error encountered.'
我认为这个问题有两个方面:
- 我不明白为什么当只有一个租户的数据中有 0(零)时,这会影响所有租户。
- 理想情况下,如果其中一个字段中存在 0(零),Sum() 应该返回 0,但我无法弄清楚,我在 Sum() 函数中尝试的所有内容都无法编译。
谢谢
【问题讨论】:
-
先贴出异常。其次,EF Core 并不神奇。它生成一个返回所有结果的 SQL 查询。如果出现一个错误,则查询失败。 实际 SQL 查询是什么?
-
您是否关闭了客户端评估?过于复杂的查询(总和中的总和?)可能会强制 EF Core 加载部分结果并尝试计算客户端上的一些聚合。此外,存储无效的
ExchangeRate有什么意义?如果没有汇率,则该值应为 1(本地货币)或 NULL(缺少汇率)。如果您想在数据库中存储幻数,您需要在查询中明确处理它们 -
@PanagiotisKanavos 我已提供所要求的信息。汇率无效的原因是数据已被第三方系统导入,我们无法控制。我知道我需要在我们的查询中处理这个问题,我只是想找出处理这个问题的最佳方法。
-
这不是完整的查询(外部 SELECT 缺少一些字段和外部 SUM)但显示出了什么问题。为了计算嵌套的 SUM,EF Core 生成了一个聚合发票项目的查询和一个计算最终 SUM 的外部查询。
-
你想做什么?为什么是嵌套总和?如果您想对特定租户的 InvoiceItems 求和,您应该从
InvoiceItem开始,而不是Invoice。例如db.InvoiceItems.Where(i=>i.Invoice.OwnedBy.TenantID=.....)
标签: c# entity-framework-core ef-core-2.2