首页 > 解决方案 > dapper.fastcrud 不映射来自 postgresql 的几何数据

问题描述

我在 Postgresql 中有空间数据。例如表 planet_osm_point 有 2 个属性:

CREATE TABLE public.planet_osm_point
(
    osm_id bigint,
    way geometry(Point,3857)
)

如果我使用 dapper 进行 CRUD 操作,一切正常。但是如果我使用 Dapper.fastCRUD 那么几何的“方式”属性总是空的

OsmPoint 类:

using NetTopologySuite.Geometries;
using System.ComponentModel.DataAnnotations.Schema; 

namespace DapperTest
{
    [Table("planet_osm_point")]
    public class OsmPoint
    {
        [Column("osm_id")]
        public long OsmId { get; set; }

        [Column("way")]
        public Point Way { get; set; }
    }
}

如果我使用 Dapper,那么我会收到 Way 属性具有几何坐标:

using (NpgsqlConnection conn = new NpgsqlConnection(_connectionString))
{
    conn.Open();
    conn.TypeMapper.UseNetTopologySuite();
    var result = conn.Query<OsmPoint>("SELECT * FROM planet_osm_point LIMIT 5000").ToList();
    return result;
}

但是如果我使用 Dapper.fastCRUD 那么 Way 总是为空

using (NpgsqlConnection conn = new NpgsqlConnection(_connectionString))
{
    conn.Open();
    conn.TypeMapper.UseNetTopologySuite();
    var result = conn.Find<OsmPoint>(p=>p.Top(5000));
    return result;
}

有谁知道如何让 Dapper.fastCRUD 处理几何数据?

标签: postgresqldapperspatialdapper-fastcrud

解决方案


首先,您为 Geometry 类型创建 TypeHandler,如下所示:

public class GeometryTypeMapper : SqlMapper.TypeHandler<Geometry>
{
    public override void SetValue(IDbDataParameter parameter, Geometry value)
    {
        if (parameter is NpgsqlParameter npgsqlParameter)
        {
            npgsqlParameter.NpgsqlDbType = NpgsqlDbType.Geometry;
            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 GeometryTypeMapper());

在 FastCURD 查询之前设置属性:

OrmConfiguration.GetDefaultEntityMapping<OsmPoint>().SetProperty(p => p.way, prop => prop.SetDatabaseColumnName("way"));

推荐阅读