You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dapper读取大于decimal.MaxValue的数值时如何返回null避免查询失败

解决方案

有两种可行方案,均不需要修改数据库源数据,也能保留decimal类型的精度要求,异常数值自动返回null,下游系统无感知:

方案1:自定义Dapper类型映射(最推荐,全局生效无侵入)

Dapper支持自定义类型处理器,你可以直接重写decimal类型的解析逻辑,捕获超出范围的异常后返回null即可。
首先实现自定义TypeHandler:

public class SafeDecimalHandler : SqlMapper.TypeHandler<decimal?>
{
    public override decimal? Parse(object value)
    {
        if (value == null || value == DBNull.Value)
            return null;
        
        try
        {
            return Convert.ToDecimal(value);
        }
        // 捕获超出decimal范围的溢出异常
        catch (OverflowException)
        {
            // 可在这里加日志记录异常数值、对应行主键等信息,同步给客户排查上游问题
            return null;
        }
        catch (InvalidCastException)
        {
            return null;
        }
    }

    public override void SetValue(IDbDataParameter parameter, decimal? value)
    {
        // 只读API不需要写操作,直接按原有逻辑赋值即可
        parameter.Value = value ?? (object)DBNull.Value;
    }
}

在API服务启动时全局注册这个处理器即可生效:

SqlMapper.AddTypeHandler(new SafeDecimalHandler());
  • 无需修改任何现有查询代码,全局所有decimal?类型的字段都会自动走安全转换逻辑
  • 如果有非空decimal字段的需求,可以单独实现非空decimal的Handler,解析失败时抛出自定义的业务异常,方便内部排查问题

方案2:SQL查询层面做范围校验

如果不想改动Dapper全局配置,可以在查询SQL中提前判断数值范围,超出范围的直接返回null:

Oracle中decimal.MaxValue对应的数值为79228162514264337593543950335,最大支持28~29位有效数字,直接在查询中加判断即可:

SELECT 
    CASE 
        WHEN 待处理的数值字段 BETWEEN -79228162514264337593543950335 AND 79228162514264337593543950335 
        THEN 待处理的数值字段 
        ELSE NULL 
    END AS 待处理的数值字段
FROM 业务表名
  • 灵活度高,可以针对特定表、特定字段做针对性处理
  • 缺点是需要逐个调整涉及大数值字段的查询语句

补充说明

原来Dapper抛出的column name is <null>错误是内部转换溢出时的异常捕获逻辑缺陷导致的,使用上述方案后可以完全避免该错误,整个查询流程不会中断。

内容的提问来源于stack exchange,提问作者Oblivious Sage

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 19:27:05