ef core decimal类型默认精度和小数位设置

文章描述了一位开发者遇到的问题,即前端数据显示的数据被四舍五入到2位小数,而实际上请求和后端数据都是3位小数。问题根源在于EFCore在转换时使用的decimal类型默认精度。解决方案包括针对特定实体属性设置精度,批量修改某些字段的精度,以及全局修改EFCore对decimal类型的默认精度配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题点:

在前端某个值保存3位小数后,再刷新页面发现该数据四舍五入到2位小数

排查:

  1. 前端的问题,发现前端请求里数据确实是3位

  1. 后端的问题,经过调试跟踪发现实体里数据也是3位的,于是乎利用sql server的profiler跟踪,发现跟踪到的sql语句参数化里的decimal是(18,2)的类型,所以应该是ef core转的时候默认类型的问题

解决:

经过查询资料大概有几种修改这默认类型的方法

  1. 对某个表或者某些表的字段设置

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<XXX>().Property(e => e.XXX).HasPrecision(precision, scale);
}

如果批量的话可以类似这样

protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder)
    {
        var properties = new[]
        {
            modelBuilder.Entity<Product>().Property(product => product.Price),
            modelBuilder.Entity<Order>().Property(order => order.OrderTotal),
            modelBuilder.Entity<OrderDetail>().Property(detail => detail.Total),
            modelBuilder.Entity<Option>().Property(option => option.Price)
        };

        properties.ToList().ForEach(property =>
        {
            property.Precision = 10;
            property.Scale = 2;
        });

        base.OnModelCreating(modelBuilder);
    }
  1. 对所有实体的decimal类型的属性进行修改,即修改ef core关于decimal类型的精度默认值

ef core 6即以上:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Properties<decimal>().Configure(config => config.HasPrecision(precision, scale));
}

ef core 6以下:

protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            var fixDecimalDatas = new List<Tuple<Type, Type, string>>();
            foreach (var entityType in modelBuilder.Model.GetEntityTypes())
            {
                foreach (var property in entityType.GetProperties())
                {
                    if (Type.GetTypeCode(property.ClrType) == TypeCode.Decimal)
                    {
                        fixDecimalDatas.Add(new Tuple<Type, Type, string>(entityType.ClrType, property.ClrType, property.Name));
                    }
                }
            }

            foreach (var item in fixDecimalDatas)
            {
                modelBuilder.Entity(item.Item1).Property(item.Item2, item.Item3).HasPrecision(precision, scale);
            }
}

### Hive MySQL 中 `decimal` 类型精度标度 #### 精度 (Precision) 精度是指十进制数值中小数点前后可以存储的最大位数。对于 `decimal(precision, scale)` 来说,precision 参数定义了整个数字允许的最大有效位数。 例如,在 `decimal(5, 2)` 中,总共有 5 位有效数字,其中小数部分占用了两位[^1]。 #### 标度 (Scale) 标度指定了小数点右侧的有效位数。继续上面的例子 `decimal(5, 2)`,这意味着最多有两位位于小数点之后。因此,该字段能够保存像 `-999.99` 到 `999.99` 这样的值(不考虑正负号)。当未指定 precision 或者 scale 的时候,默认情况下会采用不同的设置;比如在 MySQL 中,默认为 `decimal(10, 0)`[^2]。 #### 使用方法 - **声明**: 定义一个具有特定精度标度的列时,需遵循如下格式: ```sql column_name DECIMAL(precision, scale) ``` - **插入数据**: 插入到此类字段的数据应符合所设定的精度标度约束条件。如果尝试存入超出这些限制的数据,则可能会引发错误或自动截断处理取决于数据库系统的配置。 - **运算**: 当执行算术操作时,结果也会受到参与计算的操作数各自的精度标度的影响。特别是在乘除法过程中,可能需要额外注意最终结果的小数位管理以避免不必要的损失准确性。 #### 示例代码展示如何创建表并插入带有不同精度标度的 decimal 值: ```sql CREATE TABLE example ( id INT PRIMARY KEY, amount DECIMAL(7, 3), price DECIMAL(6, 2) ); INSERT INTO example VALUES (1, 12345.678, 987.65); ``` 在这个例子中,amount 字段被设计成能容纳最大七位整数加上三位小数的形式,而 price 只支持六位整数加两位小数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值