Dapper如何自定义类型映射 Dapper Custom Type Handlers教程

来源:这里教程网 时间:2026-02-21 17:37:34 作者:

用Dapper做自定义类型映射,核心就一条路:实现 ITypeHandler 或继承更方便的 TypeHandler,再注册到全局处理器缓存里。不复杂但容易忽略细节。

写一个TypeHandler类

必须实现两个方法:把C#值塞进数据库参数(SetValue),以及把数据库返回值转回C#对象(Parse)。推荐继承泛型抽象类 TypeHandler,它自带类型安全,避免运行时类型转换错误。

System.Text.Json 处理 JSON 字段示例:

public class JsonTypeHandler : SqlMapper.TypeHandler
{
  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(value.ToString(), _options) ?? default;
  }
}

注册处理器

注册必须在应用启动早期完成,比如 Program.cs 的最开头,或 DI 容器初始化阶段。重复注册不会报错,但建议只注册一次。

全局注册(对所有
Product
类型生效):
SqlMapper.AddTypeHandler(new JsonTypeHandler());
检查是否注册成功:
bool has = SqlMapper.HasTypeHandler(typeof(Product)); // true
支持可空类型自动适配 —— 注册
JsonTypeHandler<product></product>
后,
Product?
也能用

实际使用时无需额外标注

Dapper 会自动匹配已注册的处理器。只要实体属性类型和注册的泛型类型一致,插入、查询都透明生效。

例如实体中有
public Product Details { get; set; }
,数据库对应字段是
NVARCHAR(MAX)
,Dapper 就会调用你写的
JsonTypeHandler<product></product>
不需要加特性(如
[SqlMapper.TypeHandler]
),也不用手动指定映射规则
若同时存在多个同类型处理器,后注册的会覆盖前面的

常见类型适配场景

除了 JSON,以下类型也常需自定义处理:

枚举存字符串:数据库存 "Active",不是 1 —— 写
TypeHandler<status></status>
Parse
里用
Enum.Parse<status>(value.ToString())</status>
DateTime 格式化存储:字段是
VARCHAR
存 "2025-12-10 18:00" ——
SetValue
转字符串,
Parse
DateTime.TryParseExact
PostgreSQL 的 JSONB:只需在
SetValue
中设
parameter.DbType = DbType.Object
,并确保驱动支持

基本上就这些。关键不在代码多寡,而在注册时机和类型匹配是否准确。

相关推荐