ASP.NET Web API向SQL Server存入Decimal值时末尾被置零的解决求助
解决Decimal值存入SQL Server时末尾被置零的问题
嘿,咱们来拆解下你遇到的这个问题:你的SQL Server字段明明是decimal(16,3),但存入1.999却变成了1.990,核心原因是实体模型和EF的配置没跟上数据库字段的精度要求,EF默认的decimal映射规则没有正确识别你需要保留3位小数。
下面给你几个靠谱的解决方法,按操作简便程度排序:
方法1:用DataAnnotations直接标记实体属性
最简单的方式就是在实体类的PAY_CASH属性上加上注解,明确告诉EF它对应的数据库字段类型:
using System.ComponentModel.DataAnnotations.Schema; public class PAY { public int ID { get; set; } public string PAY_CODE { get; set; } // 直接指定数据库字段类型为decimal(16,3) [Column(TypeName = "decimal(16,3)")] public Nullable<decimal> PAY_CASH { get; set; } }
这个注解会让EF在生成SQL语句时,严格按照decimal(16,3)的精度来处理这个属性的值,不会再自动截断小数位。
方法2:用Fluent API配置模型(适合喜欢集中管理配置的场景)
如果你习惯用Fluent API来管理EF模型配置,就在你的DbContext的OnModelCreating方法里添加对应的配置:
如果你用的是EF Core:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<PAY>() .Property(p => p.PAY_CASH) .HasColumnType("decimal(16,3)") // 指定字段类型 .IsRequired(false); // 因为是Nullable<decimal>,所以设为非必填 }
如果你用的是EF6:
protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<PAY>() .Property(p => p.PAY_CASH) .HasPrecision(16, 3) // 直接指定精度和小数位数 .IsOptional(); }
方法3:检查POST接口的参数接收是否有问题
虽然概率不高,但可以排查下:你的POST方法里接收的PAY_CASH参数,会不会在请求阶段就被截断了?比如前端传的是1.999,但后端接收到的是1.99?
可以临时加个调试输出验证下:
[HttpPost] public string AddPayROW(string PAY_CODE, decimal PAY_CASH) { // 调试用,看看接收到的数值对不对 System.Diagnostics.Debug.WriteLine($"收到的PAY_CASH值:{PAY_CASH}"); var PAY = new PAY() { PAY_CODE = PAY_CODE, PAY_CASH = PAY_CASH, }; db.PAY.Add(PAY); db.SaveChanges(); return "Row added successfully"; }
如果接收到的数值本身就不对,那就要检查前端的参数传递方式(比如JSON序列化时的精度设置)或者请求的Content-Type是否正确。
最后一步:同步数据库(如果用Code First)
要是你用的是Code First模式,修改完实体配置后,得生成新的迁移并更新数据库,确保模型配置同步到数据库里:
打开Package Manager Console,依次执行:
Add-Migration UpdatePayCashPrecision Update-Database
做完这些步骤,再存1.999就会正确保存为1.999,不会再被置零啦!
内容的提问来源于stack exchange,提问作者Zahra Momeni
相关产品推荐
相关产品推荐

