问题
If I had both SQL Server 2008 and SQL Server 2012 installed locally, I would simply try this for myself; however I only have the newer version installed and would like to keep it that way.
- SQL Server 2008 comes with an assembly
Microsoft.SqlServer.Types.dll
, major version 10. - SQL Server 2012 comes with an assembly
Microsoft.SqlServer.Types.dll
, major version 11.
Among other things, both assemblies expose a SqlGeometryBuilder type. The one notable difference between the two assembly versions is that the 2012 type has an additional overloaded method AddCircularArc
, and the 2008 type does not.
Since it's not exactly trivial (and perhaps a bad idea) to reference both assemblies in parallel, I wonder whether I can just use the 2012 version — even against a SQL Server 2008 instance, as long as I don't make use of AddCircularArc
.
Can anyone share their experience if they have tried this?
回答1:
By default SqlClient uses version 10.0 of the Microsoft.SqlServer.Types assembly (even if you reference a newer version in your project). When two different versions of that assembly are loaded at the same time you may see strange runtime exceptions like "System.InvalidCastException: Unable to cast object of type 'Microsoft.SqlServer.Types.SqlGeometry' to type 'Microsoft.SqlServer.Types.SqlGeometry'."...
The following article describes some possibilities that you have to use the newer Microsoft.SqlServer.Types assemblies with SqlClient: Breaking Changes to Database Engine Features in SQL Server 2012
The options are:
- Calling the GetSqlBytes method, instead of the Get methods (e.g. SqlGeometry.Deserialize(reader.GetSqlBytes(0)))
- Using assembly redirection in the application configuration
- Specifying a value of "SQL Server 2012" for the "Type System Version" attribute to force SqlClient to load version 11.0 of the assembly
I personally favor the "Type System Version" connection string keyword. See the MSDN article here: SqlConnection.ConnectionString Property and search for 'Type System Version'.
回答2:
I have tried using SQL Server 2012's Microsoft.SqlServer.Types.dll
against SQL Server 2008 Express.
Geometries can be
INSERT
ed as long as they don't contain circular strings; if they do contain circular strings, which SQL Server 2008 does not support, this exception gets thrown:System.Data.SqlClient.SqlException
: The incoming tabular data stream (TDS) protocol stream is incorrect. Parameter 1 (@geometry
): The supplied value is not a valid instance of data type geometry. Check the source data for invalid values.Geometries can be
SELECT
ed, but apparently only via Well-Known Text (WKT):// SELECT [Geometry].STAsText() FROM … var geometry = SqlGeometry.STGeomFromText(sqlDataReader.GetSqlChars(…), …);
If one attempts to read the geometry directly:
// SELECT [Geometry] FROM … var geometry = (SqlGeometry)sqlDataReader[…];
then the following exception gets thrown (even if no circular strings are present in the geometries):
System.InvalidCastException
: [A]Microsoft.SqlServer.Types.SqlGeometry
cannot be cast to [B]Microsoft.SqlServer.Types.SqlGeometry
.- Type A originates from
Microsoft.SqlServer.Types, Version=10.
… - Type B originates from
Microsoft.SqlServer.Types, Version=11.
…
(That exception is not thrown when
Microsoft.SqlServer.Types.dll
version 10 is used.)- Type A originates from
来源:https://stackoverflow.com/questions/14675774/is-the-sql-server-2012-version-of-microsoft-sqlserver-types-geometry-udt-backwa