首页 > 解决方案 > 使用 Dapper 调用带有地理参数的 PostgreSQL 函数时出现 NotSupportedException

问题描述

我正在使用 Dapper(使用npgsql带有插件的数据提供程序NetTopologySuite)调用带有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.Pointgeography

标签: c#postgresqldappernpgsqlnettopologysuite

解决方案


做了一些搜索后,我找到了一个不被接受的答案,解决了我的问题。

确保我添加了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());,一切正常。


推荐阅读