Map' SqlServer.Types.SqlGeometry'进入' Microsoft.Spatial'与dapper无关的SQL-Server独立地理代码的类型

时间:2018-06-04 08:39:55

标签: c# sql-server odata dapper spatial-query

我正在使用Sql server数据库。我有一些空间数据(<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> 数据类型)。我需要使用geometryC#网络项目中阅读它们。

在我的项目中,我导入了dapper nuget包,即支持OData v4。 我认为这样我的项目应该是SQL-Server独立的。

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

然后这是我正在编写的查询以及我正在用dapper做的映射:

Microsfot.Spatial.Geometry

当我运行项目时,我得到了这个错误:

  

Dapper:解析第3列时出错(DepartureCoordinates = POINT(12.496365500000024)   41.9027835) - 对象)。无法转换类型的对象   &#39; Microsoft.SqlServer.Types.SqlGeometry&#39;输入   &#39; Microsoft.Spatial.Geometry&#39;

我也尝试使用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; } ); ,但我获得了相同的错误(只是消息中的目标类型更改)。

任何人都可以帮我解决映射吗? 谢谢

1 个答案:

答案 0 :(得分:0)

我通过更改查询并创建新类型处理程序来解决:

string sql = @"SELECT ..., departureAddress.GeometryLocation.STAsText() AS DepartureCoordinates, arrivalAddress.GeometryLocation.STAsText() AS ArrivalCoordinates ...";

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

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:

Dapper.SqlMapper.AddTypeHandler(new GeometryPointTypeHandler());