可以将 .NET 4.5.2 程序集编程为使用 CLR 2.0 版 SQL Server 2008 R2

Can a .NET 4.5.2 Assembly be programmed to use CLR version 2.0 for SQL Server 2008 R2

我正在 Microsoft .NET Framework 4.5.2 中编写一个程序集,它定义了一种在数据库连接的两端使用的类型(在数据库内部以及 .NET 端的 DataTable ).

服务器是运行SQLServer 2008 R2。

SQL 服务器 CLR 版本是 v2.0.50727,windows 服务器上的 .NET 版本(2008 R2 版本也是)是 4.5.2。

由于 CLR 版本的原因,SQL 服务器实例将仅支持 .NET 3.5 及以下版本。如果不立即升级到 SQL Server 2012,我无法更改它,因为这是一个生产服务器,但我已经围绕 ASP.Net 4.5.2 构建了一个应用程序,我不相信我现在可以更改它使用 3.5。我对这些类型的经验是它们在数据连接的两端必须相同。

我必须强制将 4.5.2 类型的 .dll 限制为 CLR v2,强制编译器允许混合版本的 .NET 程序集,或者找到另一种方法绕过 [=42= 上的 CLR v2 限制] 服务器 2008 R2.

无法在我工作的时间范围内升级 SQL 服务器实例。

有人能解决这个问题吗?

更新:

作为解决方案的一部分,我在类型 class 定义中实现了 IBinarySerialize 和 Serialize 接口。我在 ToString() 和 Parse 方法中使用 XDocument。

在 .NET 方面,我使用 Dapper ORM 的存储过程调用来执行 CRUD 操作。必须使用 ToString() 方法将自定义类型发送到 SQL 服务器实例,并且 SQL 服务器使用 Parse 方法解析该类型,然后再使用 SQL 服务器.

数据的获取是使用 Read 方法从记录中完成的,并使用 ToString() 方法发送到 .NET 端。在 .NET 端,return 然后通过使用反射的 .NET 接口使用 Parse 方法存储在类型中。

它是期望 .NET 类型匹配 SQL 服务器程序集类型的反射接口。发送到 .NET 反射接口的信息包括有关创建发送到 .NET 端的信息的类型程序集的信息。

我想底线是我需要一种方法来欺骗反射接口,使其相信使用 .NET 3.5 创建的类型与以相同方式声明的 .NET 4.5.2 类型相同。

鉴于无法解决 SQL Server 2005 的 CLR 2.0 限制,您可能无法在两侧使用 完全相同的 类型、2008 和 2008 R2。我从未尝试过 mixed-version DLL,但不确定它会把你带到哪里,除非你有不同的 CLR 2.0 用法代码,因为程序集 [=] 没有任何 "new in CLR 4.0 or above" 功能可用25=]ning 在 SQL Server 2008 R2 中,在这种情况下,您不妨编写程序集以在 CLR 2.0 中工作,因为它 运行 由于向后兼容性而在 CLR 4.0 中同样有效。

您可能会考虑保存可以输入任一版本的类型的序列化表示,并暂时在 SQL 服务器端将其保存为 XMLVARBINARY , 打算在 SQL 将来升级服务器后将列升级到 UDT。但是,您始终可以在构造函数(或其他一些方法)中读取该序列化值中的 T-SQL 代码。基本上,现在它只需要在数据库方面多做一步。这有意义吗?

我确定问题是由 Dapper micro-ORM 引起的。 Dapper 处理与数据库通信的序列化和反序列化。

SQL 服务器发回信息,指示 table 它 returns 的每一列的类型。这就是自定义类型使用特定程序集的事实来源。

Dapper 使用此信息加载自定义类型的程序集,并使用反射解析类型以确定使用哪些方法。如果您使用 Dapper 或者可能是另一个 ORM,那么通信双方的类型必须定义相同。我不能说使用 Entity Framework 是否会出现同样的问题,因为我没有使用过它。我们的编程一直在为我们所有的 .NET 程序使用 Dapper/Dapper 扩展。

因此,问题的真正解决方案是采用通用的 lower-level DataTable 方法,而不是在这种情况下使用 ORM。

感谢 Solomon Rutzky 为我指明了正确的方向。

更新:

自发布此解决方案以来,我尝试了一些以前认为行不通的方法。

我使用 .NET 3.5 而不是 .NET 4.5.2 简单地重新编译了程序集,并将它们重新安装在我用于开发和测试的 SQL Server 2012 实例上。编码细节没有变化。我没有使用 async/await,这是 3.5 和 4.x 之间的主要区别,所以这不是问题。

这确实奏效了。我不必重写我用来与数据库通信以适应规避 Dapper 的 Web Api 2.2 Web 服务。 Dapper只看装配号,我没改。

这可能不适用于每个程序集,但它适用于我的应用程序集的特定情况。