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

Dapper是否支持存储过程参数自定义类型及自动类型转换?

解答:Dapper自定义类型参数的自动转换处理

好问题!其实Dapper的TypeHandler完全可以处理命令参数的类型转换,并不是只针对查询结果的投影——你之前没生效大概率是因为没正确实现或者注册Handler。针对你的场景,我们可以通过自定义TypeHandler来实现自动转换,不用每次手动处理。

1. 实现自定义TypeHandler

首先,你需要创建一个继承自SqlMapper.TypeHandler<Date>的类,同时重写参数设置和结果解析的方法(其中SetValue就是处理命令参数的核心):

public class DateTypeHandler : SqlMapper.TypeHandler<Date>
{
    // 处理从数据库查询结果转换为自定义Date类型
    public override Date Parse(object value)
    {
        if (value is DateTime dbDateTime)
        {
            return Date.FromDateTime(dbDateTime); // 假设你的Date类有对应的转换方法
        }
        throw new InvalidCastException($"无法将类型 {value.GetType().Name} 转换为自定义Date类型");
    }

    // 处理将自定义Date类型转换为数据库参数(这正是你需要自动处理的部分)
    public override void SetValue(IDbDataParameter parameter, Date value)
    {
        parameter.DbType = DbType.Date;
        parameter.Value = value.ToDateTime(); // 调用你已有的转换方法转成DateTime
    }
}

2. 注册TypeHandler

在应用程序启动时(比如Global.asax的Application_Start方法,或者其他初始化逻辑里),注册这个自定义Handler:

// 注册自定义类型处理器
SqlMapper.AddTypeHandler(new DateTypeHandler());
// 或者用泛型方式注册,效果一致
// SqlMapper.AddTypeHandler<Date>(new DateTypeHandler());

3. 简化你的存储过程调用

注册完成后,你就不需要手动转换和指定参数类型了,直接传入自定义Date类型即可:

简化版1:直接使用匿名参数

public void Execute(Date value)
{
    Execute("dbo.InsertDate", new { MyDate = value }, CommandType.StoredProcedure);
}

简化版2:使用DynamicParameters(如果需要更复杂的参数配置)

public void Execute(Date value)
{
    var parameters = new DynamicParameters();
    parameters.Add("MyDate", value); // Dapper会自动调用TypeHandler处理转换
    Execute("dbo.InsertDate", parameters, CommandType.StoredProcedure);
}

关于你之前的疑问

你之前觉得TypeHandler只用于查询结果投影,可能是因为没有实现SetValue方法,或者忘记注册Handler。Dapper从很早的版本开始就支持用TypeHandler双向处理(参数→数据库,数据库→结果),你使用的Dapper 1.60.0完全支持这个功能,不是版本限制的问题。


内容的提问来源于stack exchange,提问作者David Keaveny

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 07:52:28