Получено NotSupportedException при использовании Dapper для вызова функции PostgreSQL с аргументом geography

Я использовал Dapper (используя npgsql поставщик данных с NetTopologySuite плагин) для вызова функции PostgreSQL с geography Затем аргумент получил 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?

2 ответа

Решение

После некоторых поисков я нашел неприемлемый ответ, который решил мою проблему.

Убедитесь, что я добавил пакет https://www.nuget.org/packages/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()); и все работает отлично.

Если бы вы только что обновились до Npgsql 4, вам нужно будет использовать один из пространственных плагинов. Прочитайте [примечания к выпуску] ( http://www.npgsql.org/doc/release-notes/4.0.html).

Другие вопросы по тегам