2

我知道它不受支持,而且我知道这甚至不是一个非常好的主意。但是,我想在 SQL 表值函数中有一个 WCF 客户端。

我(似乎)注册了正确的程序集,但是在运行我的客户端时 - 我收到了 WCF 错误:

消息 6522,第 16 级,状态 1,第 1 行
System.ServiceModel.CommunicationObjectFaultedException:
 通信对象,System.ServiceModel.ChannelFactory`1[MyProxy.IMyService],
 不能用于通信,因为它处于故障状态。

Sql Server 之外的测试似乎有效——我什至没有看到 WCF 客户端尝试建立 TCP 连接。

不确定这是 WCF 还是 SQL CLR 问题,因为我对这两者都是新手.....

编辑:我了解所需的 System.ServiceModel 及其无数程序集不在经过审查的 Sql CLR 列表中。然而,

“仍然可以从您的托管存储过程、触发器、用户定义的函数、用户定义的类型和用户定义的聚合中调用不受支持的库。不受支持的库必须首先使用 CREATE ASSEMBLY 语句在 SQL Server 数据库中注册,在它可以在你的代码中使用之前。任何在服务器上注册和运行的不受支持的库都应该经过审查和测试,以确保安全性和可靠性。

4

5 回答 5

4

本文可能会帮助您找出真正的潜在异常是什么,并了解它的致命程度:

http://jdconley.com/blog/archive/2007/08/22/wcfclientwrapper.aspx(archive.org副本)

正如大卫正确所说,SQL CLR 支持有限的 .NET 程序集子集:

SQL 2005 支持的 .NET Framework 库
SQL 2005 CLR 集成编程模型限制

SQL 2008 支持的 .NET Framework 库
SQL 2008 CLR 集成编程模型限制

System.Web.Services如果端点是 WSDL 服务,是否支持这样可以帮助您摆脱困境?或者,您始终可以使用 Web 服务作为您尝试与之交谈的任何非 Web 服务 WCF 端点的代理。

于 2009-01-28T23:27:37.533 回答
3

我不太明白,但Kev 的指针终于让我进入了工作状态。WCF 客户端包装器为您提供了实际的异常 - 而不是 CommunicationObjectFaultedException,VS2008 代理为您提供了(如何解决这个问题?)。

该异常是 FileLoadException,抱怨 System.ServiceModel:

主机存储中的程序集与 GAC 中的程序集具有不同的签名。(HRESULT 异常:0x80131050)有关详细信息,请参阅 Microsoft 知识库文章 949080。

当然,KB 949080没有任何帮助,因为它仍然指的是 SQL 2005(顺便说一句,我注意到很多 SQL 2008 错误消息,并且仍然指的是 2005 - 你认为他们至少可以替换了错误消息中的文本)并在更新 .NET FX 后处理问题——这并没有发生。

不过,这确实让我想到了 32 位和 64 位的区别。我的 SQL 2008 服务器是 Server 2008 x64 上的 x64 - 因此,它同时具有 C:\Windows\Microsoft.NET\Framework 和 Framework64 文件夹。由于 SQL Server 是一个 64 位进程,并且我的程序集将在进程中托管 - 我从 Framework64 文件夹加载程序集,并从 Program Files 加载 System.IdentityModel 和 System.IdentityModel.Selectors,而不是 Program Files (x86)。

所以,我尝试了 x86 程序集 - 但尝试加载 System.Web 给出了相当神秘的错误:

程序集 'System.Web' 引用程序集 'system.web, version=2.0.0.0,culture=neutral, publickeytoken=b03f5f7f11d50a3a.',当前数据库中不存在。

嗯,是的...我猜 System.Web 可能确实引用了 System.Web。事实证明,StackOverflow已经有了这个问题的答案。虽然没有多大意义,但看起来您需要加载 System.Web 的 Framework64 版本,以及其他所有内容的常规 Framework 版本。

不幸的是,尝试该解决方案让我返回了可怕的 WCF 捕获所有 CommunicationObjectFaultedException。对 WCF 和 IDisposable 的愚蠢感到恼火,我取消了 using 和 Dispose 调用,这样我就可以 - 你知道 - 实际上看到正确的异常:

var p = new MyServiceClient(new CustomBinding(b), new EndpointAddress(uri));
var result = p.Execute(); // Don't Dispose proxy or you'll lose the actual exception.

try {
   return result.Values;
} finally {
   if (p.State != CommunicationState.Closed) {
      if (p.State != CommunicationState.Faulted) {
         p.Close();
      } else {
         p.Abort();
      }
   }
}

然后我又遇到了另一个 FileLoadException,这次是在 System.Runtime.Serialization 上,再次将我指向无用的 KB 949080。

考虑到这是 x64 的另一种怪异情况,我决定如果要加载 Framework 程序集,我可能还应该加载 Program Files (x86) System.IdentityModel 程序集。

而且 - 你知道什么......它确实有效。运行时的 IntPtr.Size 为 8 个字节......所以我被加载为 x64。将我的程序集标记为 x64(或 x86)将无法部署 - 它仅适用于 AnyCPU。在加载的程序集上运行 corflags 显示 x86 或 x64 版本的位数没有差异,所以我真的不知道问题是什么。但是,以下 CREATE ASSEMBLIES 有效:

create assembly [System.Web] 
from 'C:\Windows\Microsoft.NET\Framework64\v2.0.50727\System.Web.dll'
with permission_set = UNSAFE

create assembly [System.Messaging] 
from 'C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Messaging.dll'
with permission_set = UNSAFE

create assembly [SMDiagnostics]
from 'C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\SMDiagnostics.dll'
with permission_set = UNSAFE

CREATE ASSEMBLY [System.IdentityModel] 
from 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\System.IdentityModel.dll'
with permission_set = UNSAFE

CREATE ASSEMBLY [System.IdentityModel.Selectors] 
from 'C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\System.IdentityModel.Selectors.dll'
with permission_set = UNSAFE

CREATE ASSEMBLY [Microsoft.Transactions.Bridge] 
from 'C:\Windows\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\Microsoft.Transactions.Bridge.dll'
with permission_set = UNSAFE

然后将我的用户程序集部署为 AnyCPU。YMMV 可能在 x86 版本的 Sql Server 上。

男孩 - 我真的开始对这些东西的黄金时间还没有做好准备感到恼火。我几乎错过了 C 的简单日子。

于 2009-01-29T15:13:42.733 回答
0

至少在 SQL Server 2005 中,只有少数支持 SQL CLR 的程序集。我不相信 WCF 是其中之一。我进行了快速搜索,没有任何结果让我得出结论,2008 SQL CLR 发生了很大变化。

参考: http: //support.microsoft.com/kb/922672

于 2009-01-28T23:14:07.043 回答
0

我在尝试在 SQL CLR 中调用 WCF Web 服务时遇到了类似的问题。它从 .NET 加载了如此多的程序集,但我无法使其工作。

最终,我使用通用 WebClient 向 WCF 服务器发出 HTTP 请求,该服务器运行良好,并且需要将最少的程序集加载到 SQL Server 中。

于 2009-01-29T09:06:26.163 回答
0

我对 System.Runtime.Serialization 程序集有同样的问题。在 x64 窗口上

解决方案是,在 c:\windows\assembly 目录中找到 System.Runtime.Serialization,将其复制到其他目录并运行 CREATE ASSEMBLY sql 命令。

最好的,

于 2009-02-20T13:01:35.327 回答