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
相关产品推荐
相关产品推荐

