GAC 中的 SQLCLR 函数和 System.Runtime.Serialization

SQLCLR Function and System.Runtime.Serialization In GAC

我在 C# 中构建了一个 SQLCLR 函数,它将反序列化 JSON 和 return 一个 table.

我遇到的问题是在 SQL Server 2012 中获取正确的程序集。

为了利用 Newtonsoft 的反序列化器,我必须将以下程序集添加到 SQL 服务器:

System.ServiceModel.Internals.dll
SMDiagnostics.dll
System.Runtime.Serialization.dll
Newtonsoft.Json.dll

这一切都按计划进行了,但是当我尝试 运行 我的函数时,出现以下错误:

System.IO.FileLoadException: Could not load file or assembly 'System.Runtime.Serialization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. Assembly in host store has a different signature than assembly in GAC. (Exception from HRESULT: 0x80131050) See Microsoft Knowledge Base article 949080 for more information. ---> System.IO.FileLoadException: Could not load file or assembly 'System.Runtime.Serialization, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. Assembly in host store has a different signature than assembly in GAC. (Exception from HRESULT: 0x80131050) See Microsoft Knowledge Base article 949080 for more information.

服务器安装了 .NET 4,我尝试添加的 DLL 来自于此。但是 C:\Windows\assembly 中显示的 DLL 是版本 3.0.0.

我使用 Powershell 更新了 GAC 中的 DLL,但这只会更新位于 C:\Windows\Microsoft.NET\assembly\GAC_MSIL.

中的 DLL

我究竟如何在 C:\Windows\assembly 获取 GAC(我假设 SQL 服务器将其与之进行比较)以反映正确的程序集?

非常感谢任何帮助。

终于成功了。不确定这个答案对其他人有多大帮助,但我不得不混合使用各种来源的 dll。

基本上,我从我的本地机器上获取了所有的 dll,并将它们复制到服务器,然后尝试组合引用本地文件和 .Net 框架内的文件。

最后我不得不在服务器上引用 .Net 中的 1 个 dll,其余的则从我的本地计算机复制。

这让它开始工作,然后在移动到生产服务器时也工作了。这不是最简单的解决方案,但我只能建议处于类似情况的任何人尝试使用各种参考组合。

运行 SQL 中的这个脚本,这应该可以解决问题

改变组装[System.Runtime.Serialization] 来自 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Runtime.Serialization.dll'

(抱歉,由于它的标记方式,没看到它)

我不推荐接受的答案中采用的方法,因为它应该不会那么复杂。

SQL 服务器有自己的 CLR 主机,该主机受到高度限制。而且它只能使用一个 CLR 版本。因此 SQL Server 2005、2008 和 2008 R2 链接到 CLR 2.0 和链接到它的 .NET Framework 版本(即 2.0、3.0 和 3.5),而 SQL Server 2012 和更新版本链接到 CLR 4.0 和链接到它的 .NET Framework 版本(即 4.0 和更新版本)。所以,既然你是在 2012 年,我不确定为什么它甚至在错误消息中提到 3.0,但它并没有尝试使用那个。

报错信息中还提到了4.0版本,问题是签名不匹配。 SQL 服务器 CLR 主机的限制之一是加载到其中的任何程序集,如果也在 GAC 中找到,则必须是完全相同的版本。此问题最可能的原因是以下因素的某种组合:

  1. 服务器(即 Windows OS)以某种方式获得了 .NET Framework 更新,但 GAC 没有得到刷新。不确定您是否尝试在复制 DLL 之前先重启服务器,但这可能已经修复了它,或者可能使用 gacutil.exe 强制卸载和重新加载 [=26= 中找到的当前版本的 DLL ]C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319

  2. 您的开发机器所处的 .NET Framework 版本与 SQLCLR 程序集部署到的位置不同。最好是这些匹配。它还有助于确保在 .sqlproj 文件的 "References" 部分中,系统 DLL 的标记没有 "SpecificAttribute" 属性设置.

  3. 这是一个远景,但至少对我帮助过的两个系统来说是一个问题:.NET Framework DLL 可以是 "corrupt",在这种情况下你需要做.NET Framework 修复。您可以从控制面板 | 执行此操作程序,或者使用微软的.NET Framework Repair Tool.