实体框架/SQL Server 奇怪的小数除法行为
我的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论