使用 Dapper 调用带有地理参数的 PostgreSQL 函数时出现 NotSupportedException
Got NotSupportedException when using Dapper to call a PostgreSQL function with a geography argument
我正在使用 Dapper(使用带有 NetTopologySuite
插件的 npgsql
数据提供程序)调用带有 geography
参数的 PostgreSQL 函数然后接收到 NotSupportedException
:
System.NotSupportedException: The member _location of type NetTopologySuite.Geometries.Point cannot be used as a parameter value
at Dapper.SqlMapper.LookupDbType(Type type, String name, Boolean demand, ITypeHandler& handler) in C:\projects\dapper\Dapper\SqlMapper.cs:line 417
at Dapper.SqlMapper.CreateParamInfoGenerator(Identity identity, Boolean checkForDuplicates, Boolean removeUnused, IList`1 literals) in C:\projects\dapper\Dapper\SqlMapper.cs:line 2516
at Dapper.SqlMapper.GetCacheInfo(Identity identity, Object exampleParameters, Boolean addToCache) in C:\projects\dapper\Dapper\SqlMapper.cs:line 1707
at Dapper.SqlMapper.ExecuteScalarImplAsync[T](IDbConnection cnn, CommandDefinition command) in C:\projects\dapper\Dapper\SqlMapper.Async.cs:line 1207
...
但是当我使用 NpgsqlCommand
和通过 AddWithValue
方法指定的类型时它工作正常。
如何让 Dapper 将 NetTopologySuite.Geometries.Point
映射到 geography
?
你刚刚升级到 Npgsql 4,你将需要使用其中一个空间插件。阅读[发行说明] (http://www.npgsql.org/doc/release-notes/4.0.html#improved-spatial-support-postgis)。
经过一番搜索后,我找到了 unaccepted answer 解决了我的问题。
确保我添加了 Npgsql.NetTopologySuite 包并且其映射器已启用 connection.TypeMapper.UseNetTopologySuite();
然后 ADO.Net 命令可以正常工作。
我添加了自定义 Dapper.SqlMapper.TypeHandler
:
public class GeographyTypeMapper : SqlMapper.TypeHandler<Geometry> {
public override void SetValue(IDbDataParameter parameter, Geometry value) {
if (parameter is NpgsqlParameter npgsqlParameter) {
npgsqlParameter.NpgsqlDbType = NpgsqlDbType.Geography;
npgsqlParameter.NpgsqlValue = value;
} else {
throw new ArgumentException();
}
}
public override Geometry Parse(object value) {
if (value is Geometry geometry) {
return geometry;
}
throw new ArgumentException();
}
}
然后使用它SqlMapper.AddTypeHandler(new GeographyTypeMapper());
,一切正常。
我正在使用 Dapper(使用带有 NetTopologySuite
插件的 npgsql
数据提供程序)调用带有 geography
参数的 PostgreSQL 函数然后接收到 NotSupportedException
:
System.NotSupportedException: The member _location of type NetTopologySuite.Geometries.Point cannot be used as a parameter value
at Dapper.SqlMapper.LookupDbType(Type type, String name, Boolean demand, ITypeHandler& handler) in C:\projects\dapper\Dapper\SqlMapper.cs:line 417
at Dapper.SqlMapper.CreateParamInfoGenerator(Identity identity, Boolean checkForDuplicates, Boolean removeUnused, IList`1 literals) in C:\projects\dapper\Dapper\SqlMapper.cs:line 2516
at Dapper.SqlMapper.GetCacheInfo(Identity identity, Object exampleParameters, Boolean addToCache) in C:\projects\dapper\Dapper\SqlMapper.cs:line 1707
at Dapper.SqlMapper.ExecuteScalarImplAsync[T](IDbConnection cnn, CommandDefinition command) in C:\projects\dapper\Dapper\SqlMapper.Async.cs:line 1207
...
但是当我使用 NpgsqlCommand
和通过 AddWithValue
方法指定的类型时它工作正常。
如何让 Dapper 将 NetTopologySuite.Geometries.Point
映射到 geography
?
你刚刚升级到 Npgsql 4,你将需要使用其中一个空间插件。阅读[发行说明] (http://www.npgsql.org/doc/release-notes/4.0.html#improved-spatial-support-postgis)。
经过一番搜索后,我找到了 unaccepted answer 解决了我的问题。
确保我添加了 Npgsql.NetTopologySuite 包并且其映射器已启用 connection.TypeMapper.UseNetTopologySuite();
然后 ADO.Net 命令可以正常工作。
我添加了自定义 Dapper.SqlMapper.TypeHandler
:
public class GeographyTypeMapper : SqlMapper.TypeHandler<Geometry> {
public override void SetValue(IDbDataParameter parameter, Geometry value) {
if (parameter is NpgsqlParameter npgsqlParameter) {
npgsqlParameter.NpgsqlDbType = NpgsqlDbType.Geography;
npgsqlParameter.NpgsqlValue = value;
} else {
throw new ArgumentException();
}
}
public override Geometry Parse(object value) {
if (value is Geometry geometry) {
return geometry;
}
throw new ArgumentException();
}
}
然后使用它SqlMapper.AddTypeHandler(new GeographyTypeMapper());
,一切正常。