Dapper自定义类型映射核心是实现ITypeHandler或继承TypeHandler并全局注册;需重写SetValue和Parse方法,推荐用TypeHandler保障类型安全,注册须在启动早期且唯一,Dapper自动匹配无需额外标注。

用Dapper做自定义类型映射,核心就一条路:实现 ITypeHandler 或继承更方便的 TypeHandler
写一个TypeHandler类
必须实现两个方法:把C#值塞进数据库参数(SetValue),以及把数据库返回值转回C#对象(Parse)。推荐继承泛型抽象类 TypeHandler
- 用 System.Text.Json 处理 JSON 字段示例:
public class JsonTypeHandler
{
private readonly JsonSerializerOptions _options = new() { PropertyNameCaseInsensitive = true };
public override void SetValue(IDbDataParameter parameter, T value)
{
parameter.DbType = DbType.String;
parameter.Value = JsonSerializer.Serialize(value, _options) ?? string.Empty;
}
public override T Parse(object value)
{
if (value == null || value is DBNull) return default;
return JsonSerializer.Deserialize
}
}
注册处理器
注册必须在应用启动早期完成,比如 Program.cs 的最开头,或 DI 容器初始化阶段。重复注册不会报错,但建议只注册一次。
- 全局注册(对所有
Product类型生效):
SqlMapper.AddTypeHandler(new JsonTypeHandler()); - 检查是否注册成功:
bool has = SqlMapper.HasTypeHandler(typeof(Product)); // true - 支持可空类型自动适配 —— 注册
JsonTypeHandler后,Product?也能用
实际使用时无需额外标注
Dapper 会自动匹配已注册的处理器。只要实体属性类型和注册的泛型类型一致,插入、查询都透明生效。
- 例如实体中有
public Product Details { get; set; },数据库对应字段是NVARCHAR(MAX),Dapper 就会调用你写的JsonTypeHandler - 不需要加特性(如
[SqlMapper.TypeHandler]),也不用手动指定映射规则 - 若同时存在多个同类型处理器,后注册的会覆盖前面的
常见类型适配场景
除了 JSON,以下类型也常需自定义处理:
-
枚举存字符串:数据库存 "Active",不是 1 —— 写
TypeHandler,Parse里用Enum.Parse(value.ToString()) -
DateTime 格式化存储:字段是
VARCHAR存 "2025-12-10 18:00" ——SetValue转字符串,Parse用DateTime.TryParseExact -
PostgreSQL 的 JSONB:只需在
SetValue中设parameter.DbType = DbType.Object,并确保驱动支持
基本上就这些。关键不在代码多寡,而在注册时机和类型匹配是否准确。










