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 类型(SqlGeometrySqlGeographySqlHierarchyID)读取数据时,标准 ADO.NET 方法(例如 DataReader.GetValues()) 使用 10.0.0.0 程序集,并由于与加载的(v11 或 v12)版本不匹配而抛出异常。

Breaking Changes in SQL Server 2012(对于 11.0.0.0 程序集)中记录了推理(尽管需要一段时间才能发现)。对于 SQL Server 2012,列出了三个解决方法:

在安装了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 服务器的版本:

问题: 除了重新映射 v10.0.0.0v12.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 年将使用的任何版本)。