NHibernate写入Decimal字段精度不符求助:需(11,8)却写为(7,5)
我之前也踩过NHibernate处理Decimal类型的坑,针对你遇到的「写入时总是用(7,5)精度,而数据库是(11,8)」的问题,给你几个实用的排查和解决方向:
1. 修正映射配置的精度参数(最常见的错误点)
你当前的映射里把precision和scale搞反了!NHibernate的precision对应数据库DECIMAL类型的总位数(也就是括号里的第一个数字),scale对应小数位数(第二个数字)。你的数据库是DECIMAL(11,8),所以正确的映射应该是:
<property name="Longitude"> <column name="Longitude" sql-type="decimal(11,8)" precision="11" scale="8" /> </property>
之前的配置写了precision="8",相当于告诉NHibernate总位数是8、小数位默认(或者被方言覆盖为5),这就导致了和数据库定义不匹配的问题。
2. 显式指定完整的sql-type
直接在sql-type里写decimal(11,8),而不是只写decimal。这样NHibernate会直接使用这个完整类型生成SQL,不会依赖默认推断的精度,避免方言或者配置的默认值干扰。
3. 检查NHibernate方言配置
不同数据库的方言对Decimal的默认精度处理可能不一样,比如一些旧版本的MySQL方言默认Decimal精度就是(7,5)。你需要确保使用的方言和你的数据库版本匹配:
- 如果是MySQL,使用
MySQL5Dialect或更高版本的方言(比如MySQL8Dialect) - 如果是SQL Server,使用
MsSql2012Dialect及以上版本
以代码配置为例:
var cfg = new Configuration(); cfg.DataBaseIntegration(db => { db.Dialect<MySQL8Dialect>(); // 替换为你对应的方言 db.ConnectionString = "你的连接字符串"; // 其他数据库配置... });
4. 统一配置方式,避免冲突
如果你同时使用了XML映射和DataAnnotations注解(比如[Column(TypeName = "decimal(11,8)")]),要确保两者的配置一致,否则NHibernate可能会优先使用其中一种,导致配置不生效。建议只保留一种配置方式,避免混淆。
5. 查看生成的SQL日志,验证配置是否生效
开启NHibernate的SQL日志,检查插入/更新时生成的SQL参数类型,确认是否正确使用了decimal(11,8)。在NHibernate配置文件中添加以下配置即可开启日志:
<property name="show_sql">true</property> <property name="format_sql">true</property>
如果日志里看到参数类型是decimal(7,5),说明配置还没生效,需要回头检查前面的步骤。
按照上面的步骤调整后,应该就能让NHibernate以(11,8)的精度写入Longitude字段了。
内容的提问来源于stack exchange,提问作者Thiago Caldeira

