You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Npgsql 8.0.2中替代GlobalTypeMapper的Fluent NHibernate映射方案

解决Npgsql v8.0.2中Fluent NHibernate复合类型映射及存储过程调用问题

问题背景

迁移至Npgsql v8.0.2后,原有的NpgsqlConnection.GlobalTypeMapper已过时,需要在Fluent NHibernate配置中替代全局类型映射,同时调用接收stock_item_price[]类型参数的存储过程时出现报错:

不支持为未设置NpgsqlDbType或DataTypeName的参数写入'System.Collections.Generic.List`1[[X.StockPriceDto, X, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'类型的值。请尝试将其中一个值设置为预期的数据库类型。

解决方案

1. 用NpgsqlDataSource替代全局类型映射

Npgsql v8推荐使用数据源级别的类型配置替代全局映射,避免全局状态冲突。在Fluent NHibernate中配置步骤如下:

// 1. 构建Npgsql数据源并配置复合类型映射
var dataSourceBuilder = new NpgsqlDataSourceBuilder("你的数据库连接字符串");
var nameTranslator = new NpgsqlSnakeCaseNameTranslator();
// 映射C#类型StockPriceDto到Postgres的stock_item_price复合类型
dataSourceBuilder.MapComposite<StockPriceDto>("stock_item_price", nameTranslator);
var dataSource = dataSourceBuilder.Build();

// 2. 配置Fluent NHibernate使用该数据源
var sessionFactory = Fluently.Configure()
    .Database(PostgreSQLConfiguration.PostgreSQL82
        .ConnectionProvider<NpgsqlDataSourceConnectionProvider>()
        .SetProperty(NHibernate.Cfg.Environment.DataSource, dataSource))
    // 添加你的实体映射等其他配置
    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<你的实体类>())
    .BuildSessionFactory();

2. 调整存储过程调用的参数配置

调用存储过程时,需要明确指定参数的数据库类型,让Npgsql正确识别复合类型数组:

方式一:指定DataTypeName

command.CommandText = "Call stock_price_save(@list)";
var listParam = command.CreateParameter();
listParam.ParameterName = "list";
// 直接指定Postgres的数组类型名称
listParam.DataTypeName = "stock_item_price[]";
listParam.Value = data; // IList<StockPriceDto>
command.Parameters.Add(listParam);
command.ExecuteNonQuery();

方式二:使用NpgsqlParameter指定类型

command.CommandText = "Call stock_price_save(@list)";
var listParam = new NpgsqlParameter
{
    ParameterName = "list",
    // 标记为复合类型数组
    NpgsqlDbType = NpgsqlDbType.Array | NpgsqlDbType.Composite,
    // 指定基础复合类型名称
    DataTypeName = "stock_item_price",
    Value = data // IList<StockPriceDto>
};
command.Parameters.Add(listParam);
command.ExecuteNonQuery();

说明

  • 数据源级别的映射是Npgsql v8的官方推荐方案,相比全局映射更灵活、更安全,避免不同连接池之间的类型配置冲突。
  • 调用存储过程时必须明确指定参数的数据库类型,否则Npgsql无法自动推断复合类型数组的映射关系。

内容的提问来源于stack exchange,提问作者xurc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 20:35:23