从 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++ 转移到 python
将 UDF 从 MS SQL Server 移植到 MySQL 会引发异常不正确的双精度值