Ben Pretorius
Ben Pretorius

Reputation: 4319

SqlGeography Type Mismatch

I have encountered the following error while writing an internal API. What I am trying to do is read a SqlGeography value (SQL Server 2012) in the following fashion:

field: public SqlGeography XY { get; set; }

object dbValue = reader["xy"];
PropertyInfo info = type.GetProperty(columnName:"xy");
info.SetValue(entity, dbValue);

Now while this might look strange, the reason I am reading in this fashion is because it is part of a Wrapper that I wrote which we use to speed up sql read and write. It takes an anonymous object and reads all the sql values into it based either on the property names or the attribute names.

This works fine for everything except SqlGeography. I did a type comparison and it fails as well so as hacky as it is I can not even do a check to see if the column is of type SqlGeography as it always fails the comparison to Microsoft.SqlServer.Types.SqlGeography.

The initial exception is as follows:

Object of type 'Microsoft.SqlServer.Types.SqlGeography' cannot be converted to t ype 'Microsoft.SqlServer.Types.SqlGeography'.

If anything is unclear then please fire away and I will try to elaborate.

Thanks!

Upvotes: 2

Views: 2411

Answers (2)

Dave R.
Dave R.

Reputation: 7304

You could have a version mismatch on the Types assembly. This was a known issue between versions 10 and 11. Unfortunately the error message doesn't include version information, which is why it looks like nonsense!

To get around it, you can deserialize the type's binary representation, i.e. something like this (if your geography column is the first in the result set):

var geo = SqlGeography.Deserialize(reader.GetSqlBytes(0));

There are other workarounds, include doing a binding redirect for the assembly.

More info here: https://connect.microsoft.com/SQLServer/feedback/details/685654/invalidcastexception-retrieving-sqlgeography-column-in-ado-net-data-reader

Upvotes: 5

Anben PANGLOSE
Anben PANGLOSE

Reputation: 116

I am using

DataTable dt;
//...
dt.Load(reader)

to load all rows from a sql table into a DataTable, so i cannot use the solution proposed by Dave R. My solution is to modify the sql select query used to create the SqlDataReader to transform the SqlGeography column to a string. example:

Original sql query:

SELECT [SpatialColumn] as SpatialData FROM [SpatialTable]

Modified sql query:

SELECT [SpatialColumn].STAsText() as SpatialData FROM [SpatialTable]

then you have to change your c# code to parse the string into a real SqlGeography like this:

using Microsoft.SqlServer.Types.SqlGeography;

string spatialData = (string) dt.Rows[0]["SpatialData"];
SqlGeography geoGraphy = SqlGeography.Parse(new System.Data.SqlTypes.SqlString(spatialData ));

Anben.

Upvotes: 1

Related Questions