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 中找到,则必须是完全相同的版本。此问题最可能的原因是以下因素的某种组合:
服务器(即 Windows OS)以某种方式获得了 .NET Framework 更新,但 GAC 没有得到刷新。不确定您是否尝试在复制 DLL 之前先重启服务器,但这可能已经修复了它,或者可能使用 gacutil.exe
强制卸载和重新加载 [=26= 中找到的当前版本的 DLL ]C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319
您的开发机器所处的 .NET Framework 版本与 SQLCLR 程序集部署到的位置不同。最好是这些匹配。它还有助于确保在 .sqlproj 文件的 "References" 部分中,系统 DLL 的标记没有 "SpecificAttribute" 属性设置.
这是一个远景,但至少对我帮助过的两个系统来说是一个问题:.NET Framework DLL 可以是 "corrupt",在这种情况下你需要做.NET Framework 修复。您可以从控制面板 | 执行此操作程序,或者使用微软的.NET Framework Repair Tool.
我在 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 中找到,则必须是完全相同的版本。此问题最可能的原因是以下因素的某种组合:
服务器(即 Windows OS)以某种方式获得了 .NET Framework 更新,但 GAC 没有得到刷新。不确定您是否尝试在复制 DLL 之前先重启服务器,但这可能已经修复了它,或者可能使用
gacutil.exe
强制卸载和重新加载 [=26= 中找到的当前版本的 DLL ]C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319您的开发机器所处的 .NET Framework 版本与 SQLCLR 程序集部署到的位置不同。最好是这些匹配。它还有助于确保在 .sqlproj 文件的 "References" 部分中,系统 DLL 的标记没有 "SpecificAttribute" 属性设置.
这是一个远景,但至少对我帮助过的两个系统来说是一个问题:.NET Framework DLL 可以是 "corrupt",在这种情况下你需要做.NET Framework 修复。您可以从控制面板 | 执行此操作程序,或者使用微软的.NET Framework Repair Tool.