dapper.fastcrud 没有映射来自 postgresql 的几何数据
dapper.fastcrud doesn't mapped geometry data from postgresql
我在 Postgresql 中有一个空间数据。例如 table planet_osm_point 有 2 个属性:
CREATE TABLE public.planet_osm_point
(
osm_id bigint,
way geometry(Point,3857)
)
如果我使用小巧的 CRUD 操作一切正常。但是如果我使用 Dapper.fastCRUD 那么 "way" 属性 和 geometry 总是 null
Class 渗透点:
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 属性 has geometry coordinats:
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 总是 null
using (NpgsqlConnection conn = new NpgsqlConnection(_connectionString))
{
conn.Open();
conn.TypeMapper.UseNetTopologySuite();
var result = conn.Find<OsmPoint>(p=>p.Top(5000));
return result;
}
有谁知道如何 Dapper.fastCRUD 使用几何数据?
首先像这样为几何类型创建 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"));
Dapper.FastCRUD 默认仅使用简单的 sql 类型来构建查询。
您可以在 Dapper.FastCrud.Configuration.OrmConventions.cs:
中看到它
public virtual IEnumerable<PropertyDescriptor> GetEntityProperties(Type entityType)
{
return TypeDescriptor.GetProperties(entityType)
.OfType<PropertyDescriptor>()
.Where(propDesc =>
!propDesc.Attributes.OfType<NotMappedAttribute>().Any()
&& !propDesc.IsReadOnly
&& propDesc.Attributes.OfType<EditableAttribute>().All(editableAttr => editableAttr.AllowEdit)
&& this.IsSimpleSqlType(propDesc.PropertyType));
}
我覆盖了 IsSimpleSqlType(Type propertyType) 方法:
public class GeometryConvention: OrmConventions
{
protected override bool IsSimpleSqlType(Type propertyType)
{
var res = base.IsSimpleSqlType(propertyType) || propertyType.BaseType != null && propertyType.BaseType.Name.StartsWith("geometry", StringComparison.OrdinalIgnoreCase);
return res;
}
}
注册自定义约定:
OrmConfiguration.Conventions = new GeometryConvention();
并使用自定义 GeometryTypeMapper,例如 Long Ngô Thành 的回答。
我在 Postgresql 中有一个空间数据。例如 table planet_osm_point 有 2 个属性:
CREATE TABLE public.planet_osm_point
(
osm_id bigint,
way geometry(Point,3857)
)
如果我使用小巧的 CRUD 操作一切正常。但是如果我使用 Dapper.fastCRUD 那么 "way" 属性 和 geometry 总是 null
Class 渗透点:
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 属性 has geometry coordinats:
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 总是 null
using (NpgsqlConnection conn = new NpgsqlConnection(_connectionString))
{
conn.Open();
conn.TypeMapper.UseNetTopologySuite();
var result = conn.Find<OsmPoint>(p=>p.Top(5000));
return result;
}
有谁知道如何 Dapper.fastCRUD 使用几何数据?
首先像这样为几何类型创建 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"));
Dapper.FastCRUD 默认仅使用简单的 sql 类型来构建查询。 您可以在 Dapper.FastCrud.Configuration.OrmConventions.cs:
中看到它public virtual IEnumerable<PropertyDescriptor> GetEntityProperties(Type entityType)
{
return TypeDescriptor.GetProperties(entityType)
.OfType<PropertyDescriptor>()
.Where(propDesc =>
!propDesc.Attributes.OfType<NotMappedAttribute>().Any()
&& !propDesc.IsReadOnly
&& propDesc.Attributes.OfType<EditableAttribute>().All(editableAttr => editableAttr.AllowEdit)
&& this.IsSimpleSqlType(propDesc.PropertyType));
}
我覆盖了 IsSimpleSqlType(Type propertyType) 方法:
public class GeometryConvention: OrmConventions
{
protected override bool IsSimpleSqlType(Type propertyType)
{
var res = base.IsSimpleSqlType(propertyType) || propertyType.BaseType != null && propertyType.BaseType.Name.StartsWith("geometry", StringComparison.OrdinalIgnoreCase);
return res;
}
}
注册自定义约定:
OrmConfiguration.Conventions = new GeometryConvention();
并使用自定义 GeometryTypeMapper,例如 Long Ngô Thành 的回答。