Получил 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?


person phqb    schedule 07.07.2018    source источник


Ответы (2)


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

Убедитесь, что я добавил пакет Npgsql.NetTopologySuite и его сопоставитель включен connection.TypeMapper.UseNetTopologySuite();, а затем ADO. Сетевая команда работает нормально.

Я добавил пользовательский 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()); и все работает нормально.

person phqb    schedule 08.07.2018

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

person Shay Rojansky    schedule 07.07.2018
comment
Мне удалось сопоставить Point с geography с помощью плагина NetToologySuite, но Даппер не понял этого сопоставления. Я также отредактировал свой вопрос, чтобы сделать его более понятным. - person phqb; 08.07.2018