【发布时间】:2021-07-23 12:48:41
【问题描述】:
所以我看到一些非常奇怪的行为,我无法弄清楚出了什么问题,希望有人能提供帮助。最初我在一个具有很多值的更大应用程序中看到了这一点,但我已将其简化为一个简单的示例。
测试代码:
[Test]
public void DecimalIssue()
{
decimal decimalValueToSet = 0.00003110M;
var modelToAdd = new TestModel { Value = decimalValueToSet };
TestModel addedEntity = _db.Add(modelToAdd);
int idToUse = addedEntity.Id;
decimal? addedValue1 = addedEntity.Value;
//int idToUse = 1;
TestModel entity = _db.GetById(idToUse);
decimal? value1 = entity.Value; // Sometimes value1 is 0.00000000 and sometimes it's 0.00003110
decimal value2 = entity.Value.Value;
decimal? value3 = Convert.ToDecimal(entity.Value);
double value4 = Convert.ToDouble(entity.Value);
decimal? value5 = decimalValueToSet;
entity.Value = decimalValueToSet;
TestModel updatedEntity = _db.Update(entity);
decimal? updatedValue = updatedEntity.Value;
TestModel newEntity = _db.GetById(idToUse);
decimal? newValue = newEntity.Value;
}
重现问题的步骤:
- 首先通过 SQL 数据库项目和 VS 架构比较添加表
- 运行测试以将值添加到数据库。调试测试时一切看起来都正确
- 检查 SSMS 中的 db 表。该值显示为 0.00000000
- 运行相同的测试,但注释掉添加部分并取消注释 idToUse = 1
- 现在我看到奇怪的代码问题,例如 entity.Value 是 0.00003110,但 value1 - value4 都是 0.00000000,但 updatedValue 和 newValue 是正确的。
- 测试结束后DB值还是0.00000000
- 直接将SSMS中的DB值更新为0.00003110。再次运行测试,现在测试中的一切都正确,之后 SSMS 中的 DB 值也正确
- 添加新值的行为与第一个相同
- 删除表并重新创建,一切都回到了正方形 1
环境详情:
- SQL 数据库项目 - 通过 VS 架构比较更新数据库架构
- Azure SQL 数据库
- .net 5
- EF6
- VS 2019 - 16.9.4
- SSMS - 18.9.1
不确定这是否有帮助,但我添加的大多数值在 SSMS 中显示为 0.00000000,但有些值显示不同。例如,如果我改为使用 0.50516090M,则它在 SSMS 中显示为 0.50000000。
型号:
[Table("Test")]
public class TestModel
{
[Key]
public int Id { get; set; }
public decimal? Value { get; set; }
}
数据库架构:
CREATE TABLE [dbo].[Test] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Value] DECIMAL (12, 8) NULL,
CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED ([Id] ASC)
);
【问题讨论】:
-
小数精度问题通常是由于模型不匹配(错误的比例和精度)或参数类型推断(默认情况下,小数将使用可能的最高位数传递,这听起来像好主意,但实际上并非如此,因为即使是最简单的计算也会导致它们失去小数位的精度)。这里有一点阻抗不匹配,因为 C#
decimals 是可变精度的,但 T-SQL 的DECIMAL类型是固定精度的。 -
@JeroenMostert 这看起来像是对我的回答 ;-)
-
不是,因为问题包含的细节太少,无法确认这是怎么回事(没有数据库层或数据库模式的代码)。这只是我最好的猜测,我希望 OP 可以用它来更深入地挖掘。
-
对不起,我忘了说 db 列设置为:"[Value] DECIMAL (12, 8) NULL"
-
而模型值只是“public decimal? Value { get; set; }”
标签: c# azure-sql-database visual-studio-2019 .net-5 database-project