我正在使用Sql server数据库。我有一些空间数据(<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
数据类型)。我需要使用geometry
在C#
网络项目中阅读它们。
在我的项目中,我导入了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;
}
);
,但我获得了相同的错误(只是消息中的目标类型更改)。
任何人都可以帮我解决映射吗? 谢谢
答案 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());