Dapper不支持PostgreSQL单个复合类型?求原因及排查方向
Dapper处理PostgreSQL单个复合类型参数报错的原因与解决方案
问题背景
定义.NET记录Model,包含单个UserTimestamp类型属性A、B及数组属性C,其中UserTimestamp已通过DataSourceBuilder.MapComposite<UserTimestamp>("usertimestamp")完成与PostgreSQL复合类型usertimestamp的映射。使用Dapper操作时,单个复合类型属性抛出NotSupportedException,改为数组类型后操作恢复正常。
核心原因
- Dapper的参数映射逻辑默认仅对基础类型、数组/集合等内置支持类型做自动处理,无法自动识别单个自定义复合类型实例与PostgreSQL复合类型的关联,因此不会触发Npgsql的复合类型序列化逻辑,导致报错。
- 数组类型能正常工作,是因为Npgsql内置支持数组的映射处理,Dapper可直接将数组参数传递给Npgsql,触发对应的序列化流程。
解决方案
方案1:手动构建Npgsql参数
在执行Dapper命令时,为单个复合类型属性手动创建NpgsqlParameter,指定复合类型元数据:
var model = new Model( A: new UserTimestamp(1, DateTime.Now), B: new UserTimestamp(2, DateTime.Now), C: new[] { new UserTimestamp(3, DateTime.Now) } ); var parameters = new DynamicParameters(); // 处理单个复合类型参数A parameters.Add("A", model.A, DbType.Object, ParameterDirection.Input); var npgsqlParamA = (NpgsqlParameter)parameters.GetDbParameter("A"); npgsqlParamA.NpgsqlDbType = NpgsqlDbType.Composite; npgsqlParamA.TypeName = "usertimestamp"; // 同理处理参数B parameters.Add("B", model.B, DbType.Object, ParameterDirection.Input); var npgsqlParamB = (NpgsqlParameter)parameters.GetDbParameter("B"); npgsqlParamB.NpgsqlDbType = NpgsqlDbType.Composite; npgsqlParamB.TypeName = "usertimestamp"; // 数组参数C直接正常添加 parameters.Add("C", model.C); // 执行Dapper命令 connection.Execute("INSERT INTO your_table (a, b, c) VALUES (@A, @B, @C)", parameters);
方案2:自定义Dapper类型处理器
实现SqlMapper.TypeHandler<UserTimestamp>,让Dapper自动处理单个复合类型实例的参数映射:
public class UserTimestampTypeHandler : SqlMapper.TypeHandler<UserTimestamp> { public override void SetValue(IDbDataParameter parameter, UserTimestamp value) { var npgsqlParam = (NpgsqlParameter)parameter; npgsqlParam.NpgsqlDbType = NpgsqlDbType.Composite; npgsqlParam.TypeName = "usertimestamp"; npgsqlParam.Value = value; } public override UserTimestamp Parse(object value) { // 若需要支持查询结果的反序列化,在此实现逻辑 return (UserTimestamp)value; } }
在应用启动时注册该类型处理器:
SqlMapper.AddTypeHandler(new UserTimestampTypeHandler());
注册后,直接使用Model原结构执行Dapper操作即可,无需手动处理参数。
内容的提问来源于stack exchange,提问作者breiter
相关产品推荐
相关产品推荐

