我有一个 CLR 存储过程,当从 SQL Server 2012 - 2017 部署到本地 SQL Server 实例时,它可以正确执行。我可以成功部署到 Azure SQL 托管实例,但是当我执行该过程时,出现以下错误:
无法加载文件或程序集 'System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' 或其依赖项之一。主机存储中的程序集与 GAC 中的程序集具有不同的签名。(来自 HRESULT 的异常:0x80131050)。
我尝试过使用项目引用,但无济于事 - 唯一System.Net.Http.dll
可以部署到托管实例的版本是执行错误的版本。
使用 SQLCLR 的要求/细微差别之一是加载到 GAC 和 SQL Server 的任何程序集必须是完全相同的版本(即下至补丁级别,而不仅仅是 Major.Minor.*)。因此,您的本地实例可能都使用 4.7.2(或其他),但如果托管实例使用 4.7、4.7.1、4.8 或其他任何版本,那么您将收到该错误。如果您的本地实例之一位于运行与您从中获取System.Net.Http.DLL的版本不同的 .NET Framework 版本的服务器上,您甚至会收到此错误。当然,如果您提到的所有这些不同的实例都在同一台物理服务器上运行,那么无论如何只涉及一个操作系统,所以它们当然都可以正常工作;-)。
您将需要找出托管实例上使用的特定版本,并在您的 Azure 安装脚本中使用它。您不需要在本地使用相同的版本,因为对具有相同签名的类似版本的引用应该有效。
现在,如何在托管实例上找到确切的框架版本?以下查询似乎是获取该信息的最佳方式:
O.P. replied back that the query above returned a version of 4.7:2623.0 on the
Managed Instance, and a version of 4.7:3190.0 on the local (on prem) system.
This is the source of the "Assembly in host store has a different signature than assembly in GAC" error
因此,为了使其工作,您需要找到该 DLL 的特定版本并将其打包以加载到托管实例中。
PS 这个问题是使用不受支持的 .NET Framework 库的缺点之一。它们将在 GAC 中(通常,对吗?),如果 Windows 更新(本地更新,或者他们对托管实例的主机系统执行的任何操作)更新版本,那么您的 SQLCLR 项目将停止工作。而且,如果新的不受支持的框架 DLL 被转换为混合模式程序集(托管和非托管代码),那么您将无法将新版本加载到 SQL Server 中,并且需要重新编码您的项目以不使用那个不受支持的框架程序集。
PPS 你用System.Net.Http做什么?如果它是用于 Web 服务的东西,那么你应该只使用System.Net.HttpWebRequest和
HttpWebResponse
类。您将不得不做一些额外的编码来构造和解析 Web 请求的 XML,但是这些类存在于一个完全受支持的库中。O.P. replied back with: "Correct, web services stuff."
Later, O.P. replied back with: "I've managed to successful deploy and execute a basic SQLCLR
procedure on Managed Instance using just
HttpWebRequest
andHttpWebResponse
,I think it'll be best to go down that line until Microsoft extend the list of natively supported libraries.."
PPPS 您可能想看看SQL#(我编写的一个 SQLCLR 库),因为有一个存储过程可以处理这个问题,基于
HttpWebRequest
. 它处理大多数(如果不是全部)内部管理的 HTTP 标头,允许发送自定义标头(包括用户 ID/密码,如有必要),发送 POST / GET 数据,甚至是大多数人通常忽略的其他一些内容。只是一个想法,尽管为了全面披露,虽然有免费版本,但 INET_GetWebPages仅在完整(付费)版本中。从Azure SQL 数据库托管实例 T-SQL 与 SQL Server 的差异:
然后:
这些限制之一可能是阻止您的原因;如果没有,向您的问题添加更多信息会很有帮助,例如您的 CLR 程序的作用以及您如何确认这些限制中的每一个都不适用。搜索
+CLR +"Managed Instance"
恰好产生两个结果,因此如果此处不适用,我建议与 Microsoft 支持联系。