[英]Map 'SqlServer.Types.SqlGeometry' into 'Microsoft.Spatial' types for SQL-Server-Independent geography code with dapper
I am using a Sql server database. 我正在使用Sql服务器数据库。 I have some spatial data (
geometry
data type). 我有一些空间数据(
geometry
数据类型)。 I need to read them in a C#
web project using dapper
. 我需要使用
dapper
在C#
Web项目中阅读它们。
In my project I imported Microsoft.Spatial
nuget package, that Support OData v4. 在我的项目中,我导入了支持OData v4的
Microsoft.Spatial
nuget包。 I think in this way my project should be SQL-Server-Independent. 我认为通过这种方式,我的项目应该独立于SQL Server。
First problem I have found is understand which data type I should use to map Sql geometry
data type. 我发现的第一个问题是了解应使用哪种数据类型来映射Sql
geometry
数据类型。 I am trying to use Microsfot.Spatial.Geometry
that is an abstract class. 我正在尝试使用作为抽象类的
Microsfot.Spatial.Geometry
。 But I am not sure. 但我不确定。
Then this is the query I am writing and the mapping I am doing with dapper: 然后这就是我正在编写的查询以及我正在使用dapper进行的映射:
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;
}
);
When I run the project I obtain this error: 当我运行项目时,出现以下错误:
Dapper: Error parsing column 3 (DepartureCoordinates=POINT (12.496365500000024 41.9027835) - Object).
Dapper:解析第3列时出错(DepartureCoordinates = POINT(12.496365500000024 41.9027835)-对象)。 Unable to cast object of type 'Microsoft.SqlServer.Types.SqlGeometry' to type 'Microsoft.Spatial.Geometry'.
无法将类型为“ Microsoft.SqlServer.Types.SqlGeometry”的对象转换为类型为“ Microsoft.Spatial.Geometry”的对象。
I have also tryed to use Microsoft.Spatial.GeometryPoint
but I obtain same error (just the destination type change in the message). 我也尝试过使用
Microsoft.Spatial.GeometryPoint
但是却遇到相同的错误(只是消息中的目标类型发生了变化)。
Can anyone help me to solve the mapping? 谁能帮我解决映射问题? Thank you
谢谢
I have solved by changing the query and creating a new type handler: 我已经解决了通过更改查询并创建一个新的类型处理程序:
string sql = @"SELECT ..., departureAddress.GeometryLocation.STAsText() AS DepartureCoordinates, arrivalAddress.GeometryLocation.STAsText() AS ArrivalCoordinates ...";
And this is the type handler I have written: 这是我编写的类型处理程序:
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);
}
}
I have not implemented SetValue
because I do not need it. 我没有实现
SetValue
因为我不需要它。
Finally I added the handler to dapper: 最后,我将处理程序添加到dapper中:
Dapper.SqlMapper.AddTypeHandler(new GeometryPointTypeHandler());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.