使用Fluent NHibernate将NetTopologySuite Point写入PostgreSQL失败
把过时代码迁移到使用最新库的新项目后,NetTopologySuite几何对象写入PostgreSQL功能失效,报错信息如下:
System.InvalidCastException: Writing values of 'NetTopologySuite.Geometries.Point' is not supported for parameters having NpgsqlDbType 'Bytea'.
at Npgsql.Internal.AdoSerializerHelpers.g__ThrowWritingNotSupported|1_0(Type type, PgSerializerOptions options, Nullable 1 pgTypeId, Nullable1 npgsqlDbType, Exception inner)
at Npgsql.Internal.AdoSerializerHelpers.GetTypeInfoForWriting(Type type, Nullable1 pgTypeId, PgSerializerOptions options, Nullable1 npgsqlDbType)
当前使用的配置:
数据库配置
var db = PostgreSQLConfiguration.PostgreSQL83; return db .ConnectionString(connectionstring) .AdoNetBatchSize(20) .Dialect<NHibernate.Spatial.Dialect.PostGis30Dialect>();
几何对象映射配置
Map(x => x.Geom).CustomType<PostGisGeometryType>();
解决思路
核对版本兼容性
新版本Npgsql对空间类型的处理逻辑已更新,必须确保NHibernate.Spatial、Npgsql和NetTopologySuite三者版本匹配,避免新旧版本混搭导致类型映射冲突。更新映射类型与方言
旧的PostGisGeometryType可能不适配新版Npgsql,尝试替换为NetTopologySuiteGeometryType(需确保NHibernate.Spatial是最新版);同时确认方言是否对应PostGIS版本,比如PostGIS 3.x+需使用正确的方言实现,避免默认将几何类型映射为bytea。启用Npgsql的NetTopologySuite支持
在项目初始化时显式注册NetTopologySuite类型映射,让Npgsql识别几何类型为PostGIS的geometry而非bytea:NpgsqlConnection.GlobalTypeMapper.UseNetTopologySuite();检查数据库字段类型
确认数据库中存储几何对象的字段类型是geometry(或具体如POINT),而非bytea。字段类型错误会直接导致类型转换失败。完善NHibernate空间配置
启用NHibernate的空间支持,并在映射时指定正确的空间类型和SRID:// 配置中添加空间启用设置 .SetProperty("hibernate.spatial.enabled", "true") // 映射时指定具体类型和SRID Map(x => x.Geom).CustomType<PostGisGeometryType>().Column(c => c.SqlType("geometry(Point, 4326)"));
内容的提问来源于stack exchange,提问作者Martin Horvath

