Dapper 中显式指定参数类型主要通过 DbType 属性实现,推荐使用 DynamicParameters 设置 DbType、precision、scale 等;SQL Server 专用场景可优先用 SqlDbType;复杂类型映射可用 ITypeHandler 全局定制。

在 Dapper 中,显式指定参数类型主要通过 DbType 属性完成,目的是让 Dapper 向数据库传递更准确的类型信息,避免隐式转换出错或性能损耗(比如把 int 当成 object 发送,触发 boxing 或不匹配的 SQL 类型推导)。
使用 DynamicParameters 设置 DbType
DynamicParameters 是 Dapper 提供的可扩展参数容器,支持为每个参数单独指定 DbType、SqlDbType(SQL Server 专用)、大小、方向等。
示例:插入一个带精度的 decimal 和一个日期:
var parameters = new DynamicParameters();
parameters.Add("@Price", 99.95m, DbType.Decimal, ParameterDirection.Input, precision: 18, scale: 2);
parameters.Add("@Created", DateTime.Now, DbType.DateTime2, ParameterDirection.Input);
connection.Execute("INSERT INTO Products (Price, Created) VALUES (@Price, @Created)", parameters);
-
DbType.Decimal告诉 Dapper 这是数值型,配合precision和scale可精准映射到数据库的DECIMAL(18,2) -
DbType.DateTime2比DbType.DateTime更精确,对应 SQL Server 的datetime2类型,避免截断或时区问题 - 未指定 DbType 时,Dapper 会基于 .NET 类型自动推断(如
int→DbType.Int32),但推断未必符合你的表结构预期
匿名对象 + SqlMapper.ITypeHandler(进阶场景)
如果需要对某类 .NET 类型统一指定 DbType(比如所有 long 都映射为 DbType.Int64 而非默认的 DbType.Int64 —— 其实默认就是它,但复杂类型如自定义枚举、JSON 字符串等就需要干预),可用 ITypeHandler:
public class JsonStringHandler : SqlMapper.ITypeHandler
{
public void SetValue(IDbDataParameter parameter, object value) =>
parameter.Value = JsonConvert.SerializeObject(value);
public object Parse(Type destinationType, object value) =>
JsonConvert.DeserializeObject(value.ToString(), destinationType);
}
// 注册(全局一次)
SqlMapper.AddTypeHandler(typeof(MyJsonModel), new JsonStringHandler());
注册后,Dapper 在遇到 MyJsonModel 类型参数时,会自动调用该 handler,并可内部设定 parameter.DbType = DbType.String 等。
SQL Server 专用:用 SqlDbType 更精细控制
当使用 SQL Server 且需精确匹配 sql_variant、geography、xml 等特殊类型时,直接用 SqlDbType 更可靠(DbType 是跨数据库抽象,部分类型不覆盖):
var p = new DynamicParameters();
p.Add("@Location", location, DbType.Object, ParameterDirection.Input);
// 更推荐:
p.Add("@Location", location, SqlDbType.Udt, ParameterDirection.Input) { UdtTypeName = "geography" };
-
SqlDbType.Udt+UdtTypeName显式声明自定义类型(如 geography、hierarchyid) -
SqlDbType.Xml对应 XML 列,比DbType.String更安全,避免被当成普通文本截断 - Dapper 会优先使用
SqlDbType(若设置了),再 fallback 到DbType
基本上就这些。日常多数情况用 DynamicParameters.Add(..., dbType: ...) 就够了;有特殊类型或全局映射需求再考虑 ITypeHandler 或 SqlDbType。关键不是“能不能设”,而是“该不该设”——看你的数据库字段定义是否严格,以及是否出现过类型不匹配报错或隐式转换警告。










