Entity Framework Core迁移后decimal值舍入规则变更求助
解决方案:恢复EF6风格的decimal截断行为
EF6默认对超出列小数位数的decimal值执行截断(向零取整),而EF Core 8.0默认使用四舍五入,这是导致差异的根本原因。以下是几种可行的修复方案:
1. 全局配置截断行为(推荐)
在DbContext的OnModelCreating方法中,全局设置所有decimal类型属性的舍入模式为截断,无需逐个修改实体:
protected override void OnModelCreating(ModelBuilder modelBuilder) { foreach (var entityType in modelBuilder.Model.GetEntityTypes()) { foreach (var property in entityType.GetProperties()) { if (property.ClrType == typeof(decimal) || property.ClrType == typeof(decimal?)) { property.SetPrecision(18); property.SetScale(2); // 设置舍入模式为截断(向零取整) property.SetRoundingMode(MidpointRounding.ToZero); } } } }
MidpointRounding.ToZero就是和EF6一致的截断逻辑。
2. 单个实体属性配置
如果仅需针对特定列调整,可在实体属性配置中单独设置:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<YourEntity>() .Property(e => e.TargetDecimalColumn) .HasPrecision(18, 2) .SetRoundingMode(MidpointRounding.ToZero); }
3. 手动处理值再存入
若EF Core配置未生效(如特殊场景),可在赋值前手动截断值:
// 手动截断到2位小数 entity.TargetDecimalColumn = Math.Truncate(1021.667 * 100) / 100;
这种方式直接可控,适用于需要精准控制的个别业务逻辑。
验证配置有效性
配置完成后,可通过EF Core生成的SQL语句验证:保存操作时,检查SQL是否使用ROUND(..., 2, 1)(SQL Server中第三个参数1代表截断),而非默认的ROUND(..., 2)。
内容的提问来源于stack exchange,提问作者saurabh geer
相关产品推荐
相关产品推荐

