实体框架/SQL Server 奇怪的小数除法行为

发布于 2024-12-10 02:11:55 字数 1843 浏览 1 评论 0原文

我的 SQL Server 2008 R2 数据库中有一个表,其中包含两个可为空的十进制(16,6)列。我们将它们称为“column1”和“column2”。

当我尝试针对从此表生成的实体运行 Linq 查询时:

Table.Select(r => new Foo
                  {
                     Bar = (r.Column1 + r.Column2) / 2m
                  }
            );

如果 column1 + column2 >= 15846,我会收到 System.OverflowException。异常消息仅为:

转化溢出。

经过一些尝试和错误,我成功地使查询与以下内容一起工作:

Table.Select(r => new Foo
                  {
                     Bar = (r.Column1 + r.Column2).HasValue ? 
                         (r.Column1 + r.Column2).Value / 2m : 0
                  }
            ); 

但是,我想知道是否有人可以解释初始查询出了什么问题。


编辑

第一个查询生成以下 SQL:

SELECT 
1 AS [C1], 
([Extent1].[Column1] + [Extent1].[Column2]) / cast(2 as decimal(18)) AS [C2]
FROM [dbo].[Table] AS [Extent1]

两列的值为 10000,在 SSMS 中手动运行查询,结果为 10000.0000000000000000000000000(25 个十进制零)。

第二个查询具有以下 SQL:

SELECT 
1 AS [C1], 
CASE WHEN ([Extent1].[Column1] + [Extent1].[Column2] IS NOT NULL)
     THEN ([Extent1].[Column1] + [Extent1].[Column2]) / cast(2 as decimal(18))
     ELSE cast(0 as decimal(18))
     END AS [C2]
FROM [dbo].[Table] AS [Extent1]

在 SSMS 中运行查询返回 10000.00000000000000000000(20 个十进制零)。显然,当 EF 尝试将第一个值(带有 25 个十进制零)转换为小数但第二个值(带有 20 个十进制零)时,会出现问题。

与此同时,事实证明,不可空列甚至单个decimal(16, 6) 列也会出现该问题。以下......

Table.Select(r => new Foo
                  {
                     Bar = r.Column1 / 2m
                  }
            );

抛出相同的转换异常(Column1 中的值为 20000)。

  • 为什么这两个 SQL 查询会产生两个不同的数字位数?
  • 为什么EF不能将第一个数字转换为十进制

I have a table in my SQL server 2008 R2 database which includes two nullable decimal(16,6) columns. Let's call them column1 and column2.

When I try to run a Linq query against the entity generated from this table:

Table.Select(r => new Foo
                  {
                     Bar = (r.Column1 + r.Column2) / 2m
                  }
            );

I get a System.OverflowException if column1 + column2 >= 15846. The message of the exception is only:

Conversion overflows.

With a bit of trial and error I've managed to make the query work with the following:

Table.Select(r => new Foo
                  {
                     Bar = (r.Column1 + r.Column2).HasValue ? 
                         (r.Column1 + r.Column2).Value / 2m : 0
                  }
            ); 

However, I was wondering if anyone could explain what was going wrong with the initial query.


Edit

The first query generates this SQL:

SELECT 
1 AS [C1], 
([Extent1].[Column1] + [Extent1].[Column2]) / cast(2 as decimal(18)) AS [C2]
FROM [dbo].[Table] AS [Extent1]

With a value of 10000 for both columns, running the query manually in SSMS the result is 10000.0000000000000000000000000 (25 decimal zeros).

The second query has this SQL:

SELECT 
1 AS [C1], 
CASE WHEN ([Extent1].[Column1] + [Extent1].[Column2] IS NOT NULL)
     THEN ([Extent1].[Column1] + [Extent1].[Column2]) / cast(2 as decimal(18))
     ELSE cast(0 as decimal(18))
     END AS [C2]
FROM [dbo].[Table] AS [Extent1]

Running the query in SSMS returns 10000.00000000000000000000 (20 decimal zeros). Apparently there is a problem when EF tries to convert the first value (with 25 decimal zeros) into a decimal but with the second (with 20 decimal zeros) it works.

In the meantime it turned out that the problem also occurs with non-nullable columns and even a single decimal(16, 6) column. The following ...

Table.Select(r => new Foo
                  {
                     Bar = r.Column1 / 2m
                  }
            );

... throws the same conversion exception (with a value of 20000 in the Column1).

  • Why do those two SQL queries result in two different numbers of digits?
  • And why can't the first number be converted into a decimal by EF?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文