从 C# 到 SQL Server 的精度损失

Posted

技术标签:

【中文标题】从 C# 到 SQL Server 的精度损失【英文标题】:Loss of Precision from C# to SQL Server 【发布时间】:2014-05-12 01:21:27 【问题描述】:

这是我面临的一个问题,它在从 C# Entity Framework 存储到 SQL Server 数据库时导致精度损失。

    SQL Server 数据类型为decimal(20, 15) 在 C# 中属性定义为public decimal AssignedGrossBudget get; set; 在 C# 中,变量 (AssignedGrossBudget) 中的值为 34.09090909090909 但在 SQL Server 表中是 34.090000000000000

可能出了什么问题? (我正在使用实体框架 db.SaveChanges(); 和 SQLBulkCopy 将数据从 c# 存储到 SQL Server)

我想存储 34.09090909090909 而不是 34.090000000000000。

我通过直接插入表格进行检查,它可以工作。

【问题讨论】:

能否提供批量复制的代码? 请使用 Profiler 捕获 EF 生成的准确语句,并发布文本数据。 可能你需要为EF配置精度:***.com/questions/3504660/… 是引起问题的 SaveChanges 还是 SqlBulkCopy?您不会将两者用于相同的操作,因此应该很明显应该归咎于哪一个 - 您的问题无需同时提及。 Joe:两者都有问题,但它们的操作不同。 SQL Bulk Copy 用于将数据从 Excel 上传到 SQL Server(使用 EPPlus),而 EF 用于其他 UI 操作。 【参考方案1】:

感谢 Urril 和 Remus。

我在实体框架中进行如下更改:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        
            modelBuilder.Entity<StationMapping>().Property(x => x.AssignedGrossBudget).HasPrecision(35, 15);

        

对于 SQL BulkCopy,我根据 Remus 的建议添加了数据类型。

SpotLookupTable.Columns.Add(new DataColumn("GrossBudget",typeof(decimal)));

它现在正在工作并且没有损失(或可以忽略不计)。

干杯

【讨论】:

【参考方案2】:

一个简单的例子表明,正确编写的代码不会出现这种精度损失:

    static void Main(string[] args)
    
        decimal d = 34.09090909090909M;
        Console.WriteLine(d);

        SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder();
        scsb.IntegratedSecurity = true;
        scsb.DataSource = @".\sql2012";

        using (SqlConnection conn = new SqlConnection(scsb.ConnectionString)) 
            conn.Open();

            using (SqlCommand cmd = new SqlCommand(
               "select cast(@d as DECIMAL(20,15))", conn))
            
                cmd.Parameters.AddWithValue("@d", d);
                decimal rd = (decimal) cmd.ExecuteScalar();
                Console.WriteLine(rd);
            
        
    

因此,我必须得出结论,问题出在您的代码上,没有发布。

【讨论】:

以上是关于从 C# 到 SQL Server 的精度损失的主要内容,如果未能解决你的问题,请参考以下文章

C# 中的双倍比较精度损失,加减双精度时发生精度损失

在不损失精度的情况下将双精度从 C++ 转移到 python

将 UDF 从 MS SQL Server 移植到 MySQL 会引发异常不正确的双精度值

这种精度损失发生在哪里以及如何防止它?

更改SQL Server 2014中现有十进制列的精度会导致错误

可能导致精度或幅度损失的 Java 隐式强制转换? [复制]