首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用dapper将“SqlServer.Types.SqlGeometry”映射为与Server无关的地理代码的“Microsoft.Spatial”类型

使用dapper将“SqlServer.Types.SqlGeometry”映射为与Server无关的地理代码的“Microsoft.Spatial”类型
EN

Stack Overflow用户
提问于 2018-06-04 08:39:55
回答 1查看 1.5K关注 0票数 1

我使用的是Sql服务器数据库。我有一些空间数据(geometry数据类型)。我需要在一个C#网络项目中使用dapper阅读它们。

在我的项目中,我导入了Microsoft.Spatial nuget包,它支持OData v4。我认为以这种方式,我的项目应该是与Server无关的。

我发现的第一个问题是理解应该使用哪种数据类型来映射Sql geometry数据类型。我正在尝试使用Microsfot.Spatial.Geometry,它是一个抽象类。但我不确定。

接下来是我正在编写的查询以及我正在使用dapper进行的映射:

代码语言:javascript
复制
string sql = @"SELECT ..., departureAddress.GeometryLocation AS DepartureCoordinates, arrivalAddress.GeometryLocation AS ArrivalCoordinates ...";

var infoResultset = await this._connection.QueryAsync<MyInfoClass, ..., MyInfoClass>(
    sql,
    (request, ...) =>
    {
        /* Nothing about spatial types */

        return result;
    }
);

当我运行该项目时,我会得到以下错误:

Dapper:错误解析列3 (DepartureCoordinates=POINT (12.496365500000024,41.9027835) - Object)。无法将“Microsoft.SqlServer.Types.SqlGeometry”类型的对象转换为“Microsoft.Spatial.几何学”类型。

我也尝试过使用Microsoft.Spatial.GeometryPoint,但是我获得了相同的错误(只更改了消息中的目标类型)。

有人能帮我解决地图问题吗?谢谢

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-04 15:50:36

我通过更改查询和创建一个新的类型处理程序来解决问题:

代码语言:javascript
复制
string sql = @"SELECT ..., departureAddress.GeometryLocation.STAsText() AS DepartureCoordinates, arrivalAddress.GeometryLocation.STAsText() AS ArrivalCoordinates ...";

这是我编写的类型处理程序:

代码语言:javascript
复制
public class GeometryPointTypeHandler : SqlMapper.TypeHandler<GeometryPoint>
{
    //      POINT(X Y)
    //      POINT(X Y Z M)
    public override GeometryPoint Parse(object value)
    {
        if (value == null)
            return null;

        if (!Regex.IsMatch(value.ToString(), @"^(POINT \()(.+)(\))"))
            throw new Exception("Value is not a Geometry Point");

        //Get values inside the brackets
        string geometryPoints = value.ToString().Split('(', ')')[1];

        //Split values by empty space
        string[] geometryValues = geometryPoints.Split(' ');

        double x = this.ConvertToDouble(geometryValues[0]);
        double y = this.ConvertToDouble(geometryValues[1]);

        double? z = null;
        if (geometryValues.Length >= 3)
            z = this.ConvertToDouble(geometryValues[2]);

        double? m = null;
        if (geometryValues.Length >= 4)
            m = this.ConvertToDouble(geometryValues[3]);

        return GeometryPoint.Create(x, y, z, m);
    }

    public override void SetValue(IDbDataParameter parameter, GeometryPoint value)
    {
        throw new NotImplementedException();
    }

    private double ConvertToDouble(string value)
    {
        return double.Parse(value, CultureInfo.InvariantCulture);
    }
}

我没有实现SetValue,因为我不需要它。

最后,我将处理程序添加到dapper:

代码语言:javascript
复制
Dapper.SqlMapper.AddTypeHandler(new GeometryPointTypeHandler());
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50676493

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档