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
相关产品推荐
相关产品推荐

