C# 使用ICSharpCode.SharpZipLib的项目的SQLCLR发布失败

C# 使用ICSharpCode.SharpZipLib的项目的SQLCLR发布失败,c#,sql-server,sqlclr,C#,Sql Server,Sqlclr,我有一个sql clr,它有一些函数和存储过程。我有一个外部访问模式的项目和一个签名密钥。-很好用 我在项目中添加了另一个函数,它使用了ICSharpcode.SharpZipLib。我最初得到了一个版本的不兼容错误,我想我是按照另一篇文章中的说明解决的 该项目构建得很好,但现在在项目的最后阶段(SQLServerDB项目)中出现了以下错误。这是在我的本地机器上,我有管理员权限 正在创建[ICSharpCode.SharpZipLib]。。。 (47,1):SQL72014:.Net SqlCl

我有一个sql clr,它有一些函数和存储过程。我有一个
外部访问
模式的项目和一个签名密钥。-很好用

我在项目中添加了另一个函数,它使用了
ICSharpcode.SharpZipLib
。我最初得到了一个版本的不兼容错误,我想我是按照另一篇文章中的说明解决的

该项目构建得很好,但现在在项目的最后阶段(SQLServerDB项目)中出现了以下错误。这是在我的本地机器上,我有管理员权限

正在创建[ICSharpCode.SharpZipLib]。。。
(47,1):SQL72014:.Net SqlClient数据提供程序:Msg 6211,级别16,状态1,第1行创建程序集失败,因为安全程序集“ICSharpCode.SharpZipLib”中的类型“”具有静态字段“$$method0x6000014-1”。安全组件中静态字段的属性必须在VisualC语言中只读标记,在Visual Basic中只读,或者仅在Visual C++和中间语言中读取。
(47,0):SQL72045:脚本执行错误。执行的脚本:
创建程序集[ICSharpCode.SharpZipLib]
授权[dbo]
从…起0x4D5A9000030000004000000FFFF0000B8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6E6F7420626520726E20696E20444F53206D6F64652D0A240000000000000000000005045000004C0103003877BE5A0000000000000000000000E000210B010B02000000000009E120000020000000 200200000000000000000000000000000000000000000000000000000000000000000000000000000000000600200000000000000000000000300405000000100001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004C1B02004F00000000200020038040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000008000000000000000000000000000000000000000000000820000048000000000000000000000002E7465787400000A4FB0100002000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020020000100001000000000010020000000000000000000000000000000000000400000402E727272656C6F63000000000000000000400020002000
执行批处理时出错。

谢谢你的帮助! 谢谢,
Satya

我想第一件事是看看你是否可以不用IcSharpcode.SharpZipLib。如果没有,则:

如果您有权访问IcSharpcode.SharpZipLib的源代码,则可以将静态更改为只读


最后一个选项是部署权限设置为不安全的程序集

与操作系统上运行的CLR主机相比,在SQL Server中运行的CLR主机受到高度限制。限制的一个原因是应用程序域是跨会话共享的。因此,每个执行特定SQLCLR方法(无论是存储过程、函数、用户定义类型、用户定义聚合还是触发器)的人都在同一应用程序域中的同一静态类中执行相同的方法。因此,静态类变量是共享资源,除非您在使用它们时非常小心和慎重,否则它们很容易导致竞争条件和奇怪(且难以调试)的行为

错误消息与此有关,但也有点误导,因为它提到
SAFE
程序集不允许这样的事情。更准确地说,它是非
不安全的
程序集不允许这样的事情(即既不允许
安全
也不允许
外部访问

因此,正如Niels在他的回答中提到的,您可以将程序集标记为不安全的,它将加载并可能工作。但是,除非您知道如何使用该变量(以及标记为静态但尚未提及的任何其他变量),否则如果一个会话覆盖了另一个会话仍在使用的值,则可能会导致竞争条件。或者之前的值可能会留在那里,这可能会对下一个调用者产生不利影响。在尝试将程序集设置为
不安全之前,您需要查看代码以确保这不是问题


虽然没有那么快和容易,但您确实需要从更新代码开始,将这些静态变量标记为只读,并尝试重新编译,以确保在整个代码中没有写入该变量的尝试。如果代码的其他部分确实写入该静态变量,那么您需要重构代码或找到其他代码来执行相同的操作。几年前,我遇到了这个问题,并选择将其用于我的项目,尽管我仍然需要对静态变量之类的东西进行一些小的修改。

感谢Niels和Solomon(提供了这些概念!)。我遇到了几个问题,但最终能够通过将权限设置为“不安全”来解决它。我将按照所罗门的建议,研究SharpZiplib的替代品。我没有一个干净的出版物。谢谢你的帮助@Satya正如我提到的,如果您使用的是
不安全的
选项,因此静态变量不是
只读的
,那么您需要进行大量测试,以确保不会遇到任何竞争条件。从单个会话进行测试很少会暴露任何问题。谢谢Solomon。谢谢你让我知道。我还遇到了我可以使用的GZipstream。目前正在测试,因此我可以避免使用ICSharp库。我还偶然发现了您关于SqlServerCentral上CLR的系列文章,我正在阅读。伟大的系列。喜欢你的演讲和细节。