SQL Server 2014 Native Client (12.0.0.0) - 有什么方法可以强制使用程序集版本(例如 SqlConnectionString "Type System Version")?
SQL Server 2014 Native Client (12.0.0.0) - Any way to force Assembly Version (e.g. SqlConnectionString "Type System Version")?
我正在编写一个应用程序(使用本地安装的 .NET Framework 4.5.2 + SQL Server 2014)。该应用程序需要同时支持 SQL Server 2014 和以前的版本。
使用内置 SQLCLR 类型(SqlGeometry
、SqlGeography
、SqlHierarchyID
)读取数据时,标准 ADO.NET 方法(例如 DataReader.GetValues()
) 使用 10.0.0.0 程序集,并由于与加载的(v11 或 v12)版本不匹配而抛出异常。
在 Breaking Changes in SQL Server 2012(对于 11.0.0.0 程序集)中记录了推理(尽管需要一段时间才能发现)。对于 SQL Server 2012,列出了三个解决方法:
中使用Type System Version=SQL Server 2012
或:使用app.config / runtime / assemblyBinding / dependentAssembly
重新映射v10.0.0.0到v11.0.0.0
或(不是非常 "neat" 的处理方式):重写您自己的代码以从 SqlBytes
实例手动反序列化...
在安装了SQLServer 2014的电脑上开发时,程序集版本为v12.0.0.0,出现类似问题:
System.InvalidCastException: Unable to cast object of type Microsoft.SqlServer.Types.SqlGeometry
to type Microsoft.SqlServer.Types.SqlGeometry
.
对于 SQL Server 2014(除了可怕的手动 反序列化 方法),似乎只有一种解决方法(未在重大更改中正式记录) - 看起来 v4.5 SqlConnection
还没有赶上 SQL 服务器的版本:
- 使用
app.config / runtime / assemblyBinding / dependentAssembly
重新映射v10.0.0.0到v12.0.0.0
问题: 除了重新映射 v10.0.0.0 到 v12.0.0.0 in app.config
(这似乎可行),是否有任何其他(更简单的)方法可以使用引用的程序集版本?
下面的快速代码示例显示了失败(没有适当的程序集重新映射):
private static void DoStuff()
{
SqlGeography geog_val = SqlGeography.STGeomFromText(new SqlChars("POLYGON((-122.358 47.653, -122.348 47.649, -122.348 47.658, -122.358 47.658, -122.358 47.653))"), 4326);
SqlGeometry geom_val = SqlGeometry.Parse("LINESTRING(1 1,2 3,4 8, -6 3)");
prm_geog.Value = DBNull.Value; prm_geom.Value = geom_val; ReadReturnedSpatialColumns(cmd);
prm_geog.Value = geog_val; prm_geom.Value = DBNull.Value; ReadReturnedSpatialColumns(cmd);
}
private static void ReadReturnedSpatialColumns(SqlCommand cmd)
{
using (var dr = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
dr.Read(); var items = new object[2]; dr.GetValues(items);
var geog_test = dr.IsDBNull(0) ? SqlGeography.Null : (SqlGeography)items[0];
var geom_test = dr.IsDBNull(1) ? SqlGeometry.Null : (SqlGeometry)items[1];
}
}
这个问题在 Framework 4.6.1 中仍然存在,除了您已经发现的 3 个之外似乎没有解决方法。所以对你的问题的简短回答是 no.
但是我会质疑您是否真的 需要空间类型的第 12 版,因为(据我所知)它们不会在 v11 类型上添加任何内容。如果您更喜欢使用 v11 类型以便可以使用 Type System Version=SQL Server 2012
解决方法,则可以安装包含所有三个版本(10、11、12)的 Nuget package - 它专门设计用于允许您部署到可能未安装 MSSQL 的服务器。
作为奖励,直接引用该包并使用 Type System Version=SQL Server 2012
将确保您的应用程序将始终使用 2012 空间类型,因此升级到 SQL 2016 不会破坏任何东西默认情况下,决定 return 它们的不同版本(例如 13 或 14,或 2016 年将使用的任何版本)。
我正在编写一个应用程序(使用本地安装的 .NET Framework 4.5.2 + SQL Server 2014)。该应用程序需要同时支持 SQL Server 2014 和以前的版本。
使用内置 SQLCLR 类型(SqlGeometry
、SqlGeography
、SqlHierarchyID
)读取数据时,标准 ADO.NET 方法(例如 DataReader.GetValues()
) 使用 10.0.0.0 程序集,并由于与加载的(v11 或 v12)版本不匹配而抛出异常。
在 Breaking Changes in SQL Server 2012(对于 11.0.0.0 程序集)中记录了推理(尽管需要一段时间才能发现)。对于 SQL Server 2012,列出了三个解决方法:
- 中使用
或:使用
app.config / runtime / assemblyBinding / dependentAssembly
重新映射v10.0.0.0到v11.0.0.0或(不是非常 "neat" 的处理方式):重写您自己的代码以从
SqlBytes
实例手动反序列化...
Type System Version=SQL Server 2012
在安装了SQLServer 2014的电脑上开发时,程序集版本为v12.0.0.0,出现类似问题:
System.InvalidCastException: Unable to cast object of type
Microsoft.SqlServer.Types.SqlGeometry
to typeMicrosoft.SqlServer.Types.SqlGeometry
.
对于 SQL Server 2014(除了可怕的手动 反序列化 方法),似乎只有一种解决方法(未在重大更改中正式记录) - 看起来 v4.5 SqlConnection
还没有赶上 SQL 服务器的版本:
- 使用
app.config / runtime / assemblyBinding / dependentAssembly
重新映射v10.0.0.0到v12.0.0.0
问题: 除了重新映射 v10.0.0.0 到 v12.0.0.0 in app.config
(这似乎可行),是否有任何其他(更简单的)方法可以使用引用的程序集版本?
下面的快速代码示例显示了失败(没有适当的程序集重新映射):
private static void DoStuff()
{
SqlGeography geog_val = SqlGeography.STGeomFromText(new SqlChars("POLYGON((-122.358 47.653, -122.348 47.649, -122.348 47.658, -122.358 47.658, -122.358 47.653))"), 4326);
SqlGeometry geom_val = SqlGeometry.Parse("LINESTRING(1 1,2 3,4 8, -6 3)");
prm_geog.Value = DBNull.Value; prm_geom.Value = geom_val; ReadReturnedSpatialColumns(cmd);
prm_geog.Value = geog_val; prm_geom.Value = DBNull.Value; ReadReturnedSpatialColumns(cmd);
}
private static void ReadReturnedSpatialColumns(SqlCommand cmd)
{
using (var dr = cmd.ExecuteReader(CommandBehavior.SingleRow))
{
dr.Read(); var items = new object[2]; dr.GetValues(items);
var geog_test = dr.IsDBNull(0) ? SqlGeography.Null : (SqlGeography)items[0];
var geom_test = dr.IsDBNull(1) ? SqlGeometry.Null : (SqlGeometry)items[1];
}
}
这个问题在 Framework 4.6.1 中仍然存在,除了您已经发现的 3 个之外似乎没有解决方法。所以对你的问题的简短回答是 no.
但是我会质疑您是否真的 需要空间类型的第 12 版,因为(据我所知)它们不会在 v11 类型上添加任何内容。如果您更喜欢使用 v11 类型以便可以使用 Type System Version=SQL Server 2012
解决方法,则可以安装包含所有三个版本(10、11、12)的 Nuget package - 它专门设计用于允许您部署到可能未安装 MSSQL 的服务器。
作为奖励,直接引用该包并使用 Type System Version=SQL Server 2012
将确保您的应用程序将始终使用 2012 空间类型,因此升级到 SQL 2016 不会破坏任何东西默认情况下,决定 return 它们的不同版本(例如 13 或 14,或 2016 年将使用的任何版本)。