【问题标题】:SQLCLR Function and System.Runtime.Serialization In GACGAC 中的 SQLCLR 函数和 System.Runtime.Serialization
【发布时间】:2016-04-18 19:05:05
【问题描述】:

我在 C# 中构建了一个 SQLCLR 函数,它将反序列化 JSON 并返回一个表。

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

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

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

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

System.IO.FileLoadException:无法加载文件或程序集“System.Runtime.Serialization,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089”或其依赖项之一。主机存储中的程序集与 GAC 中的程序集具有不同的签名。 (HRESULT 异常:0x80131050)有关详细信息,请参阅 Microsoft 知识库文章 949080。 ---> System.IO.FileLoadException:无法加载文件或程序集“System.Runtime.Serialization,版本=3.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089”或其依赖项之一。主机存储中的程序集与 GAC 中的程序集具有不同的签名。 (HRESULT 异常:0x80131050)有关详细信息,请参阅 Microsoft 知识库文章 949080。

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

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

究竟如何在 C:\Windows\assembly(我假设是 SQL Server 与之比较的那个)上获得 GAC 以反映正确的程序集?

非常感谢任何帮助。

【问题讨论】:

  • 你有没有想过这个问题?这会很有帮助。
  • 是的,我做到了,抱歉一直没有更新帖子。现在会这样做。

标签: .net sql-server sql-server-2012 gac sqlclr


【解决方案1】:

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

ALTER ASSEMBLY [System.Runtime.Serialization] FROM 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Runtime.Serialization.dll'

【讨论】:

  • 谢谢!我基本上做到了:CREATE ASSEMBLY [System.Runtime.Serialization]FROM 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Runtime.Serialization.dll'WITH PERMISSION_SET = UNSAFEGO
【解决方案2】:

终于设法让这个工作。不确定这个答案对其他人有多大帮助,但我不得不使用一些来自各种来源的 dll。

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

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

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

【讨论】:

  • 您是否必须使用不安全的权限?
  • 是的,别以为可以用其他方式使用自己的dll
  • 不可以,只要您遵循某些准则即可。问题是 Newtonsoft 使用了一些非只读静态变量和锁定原语。我正在修复此代码,并且还删除了对 System.Runtime.Serialozation 的引用,它仅用于 DataContract 属性,我可以不用它。 SQL Azure 只允许安全的用户库。
  • @tejas 只是好奇你是否曾经在安全组件中“正确”地工作。几年前,我开始着手进行所有这些更改,但它变得太混乱了。如果我知道可以删除所有这些静态变量引用并且仍然可以在没有“奇怪”行为的情况下继续工作,我会再试一次;-)
  • @srutzky 不幸的是,我没有走多远,因为我还需要一些转换支持,因为我从 JSON 切换到 XML。你搞定了吗?
【解决方案3】:

(抱歉,由于它是如何标记的,所以没有看到这个)

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

SQL Server 有自己的 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 Server CLR 主机的限制之一是加载到其中的任何程序集(如果也在 GAC 中找到)必须是完全相同的版本。此问题的最可能原因是以下一些组合:

  1. 不知何故,服务器(即 Windows 操作系统)获得了 .NET Framework 更新,而 GAC 没有得到刷新。不确定您是否尝试在复制 DLL 之前先重新启动服务器,但这可能已经修复它,或者可能使用gacutil.exe 强制卸载和重新加载当前版本的 DLL,如 C:\ WINDOWS\Microsoft.NET\Framework64\v4.0.30319

  2. 您的开发计算机使用的 .NET Framework 版本与 SQLCLR 程序集部署到的位置不同。如果这些匹配是最好的。它还有助于确保在 .sqlproj 文件的“参考”部分中,系统 DLL 的标记没有设置“SpecificAttribute”属性。

  3. 这是一个长期的问题,但对于我帮助过的至少两个系统来说一直是个问题:.NET Framework DLL 可能“损坏”,在这种情况下,您需要进行 .NET Framework 修复。您可以从控制面板 | 执行此操作程序,或使用微软的.NET Framework Repair Tool

【讨论】:

    猜你喜欢
    • 2011-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-21
    • 1970-01-01
    • 1970-01-01
    • 2017-07-14
    相关资源
    最近更新 更多