I know it\'s not supported, and I know it\'s not even a terribly good idea. But, I want to have a WCF client inside a SQL Table Valued Function.
I\'ve (seemingly) re
I had similar problems while trying to call WCF web services within SQL CLR. It loads so much assemblies from .NET and I couldn't make it work.
Eventually, I use generic WebClient to make HTTP request to the WCF server which works really well and it requires min assemblies loaded into SQL Server.
This article might help you find out what the true underlying exception is and to see how fatal it is:
http://jdconley.com/blog/archive/2007/08/22/wcfclientwrapper.aspx (archive.org copy)
As David correctly says, the SQL CLR has support for a limited subset of .NET assemblies:
SQL 2005 Supported .NET Framework Libraries
SQL 2005 CLR Integration Programming Model RestrictionsSQL 2008 Supported .NET Framework Libraries
SQL 2008 CLR Integration Programming Model Restrictions
System.Web.Services
is supported if the end point is a WSDL service so that might help you get out of a hole? Or you could always use a web service as a proxy to whatever non-webservice WCF endpoint you're trying to talk to.
I don't quite get it, but Kev's pointer finally led me to a working state. The WCF client wrapper gives you the actual exception - instead of the CommunicationObjectFaultedException the VS2008 proxy gives you (how has this not been fixed?).
That exception was a FileLoadException, complaining about System.ServiceModel:
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.
Of course, KB 949080 was no help, since it still refers to SQL 2005 (as an aside, I've noticed a lot of the SQL 2008 error messages and such still refer to 2005 - you'd think they could've at least replaced the text in the error messages) and deals with problems after updating the .NET FX - which hadn't happened.
That did make me think of 32-bit and 64-bit differences, though. My SQL 2008 server is x64 on Server 2008 x64 - and, as such, has both a C:\Windows\Microsoft.NET\Framework and a Framework64 folder. Since SQL Server is a 64 bit process, and my assembly would be hosted in process - I loaded the assemblies from the Framework64 folder, and System.IdentityModel and System.IdentityModel.Selectors from Program Files, as opposed to Program Files (x86).
So, I tried the x86 assemblies - but trying to load System.Web gives the rather cryptic error:
Assembly 'System.Web' references assembly 'system.web, version=2.0.0.0, culture=neutral, publickeytoken=b03f5f7f11d50a3a.', which is not present in the current database.
Well, yeah...I guess System.Web probably does reference System.Web. Turns out, StackOverflow already has an answer to this problem. Though it doesn't make much sense, it looks like you need to load the Framework64 version of System.Web, and the regular Framework versions of everything else.
Unfortunately, trying that solution gave me back the dreaded WCF catch all CommunicationObjectFaultedException. Annoyed by the stupidity of WCF and IDisposable, I did away with the using and Dispose call, so that I could - you know - actually see the correct exception:
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();
}
}
}
I then ended up with yet another FileLoadException, this time on System.Runtime.Serialization again pointing me to the useless KB 949080.
Figuring this was yet another case of x64 weirdness, I decided that if I was going to load the Framework assemblies, I should probably also load the Program Files (x86) System.IdentityModel assemblies.
And - what do you know...it actually worked. IntPtr.Size at runtime was 8 bytes...so I was being loaded as x64. Marking my assembly as x64 (or x86) would fail to deploy - it only worked with AnyCPU. Running corflags on the assemblies loaded showed no differences between the bitness of the x86 or x64 versions, so I really don't know what the problem is. But, the following CREATE ASSEMBLIES worked:
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
And then deploying my user assembly as AnyCPU. YMMV may on an x86 version of Sql Server.
Boy - I'm really starting to get annoyed at the not quite ready for prime timeness of some of this stuff. I'm almost missing the simple days of C.
I've the same problem with System.Runtime.Serialization assembly. over a x64 windows
The solution was, find the System.Runtime.Serialization in c:\windows\assembly directory, copy it to other directory and run the CREATE ASSEMBLY sql command.
Best,
At least in SQL Server 2005, there were only a handful of supported assemblies for SQL CLR. I don't believe WCF was one of them. I did a quick search, and nothing turned up to lead me to the conclusion that much has changed for 2008 SQL CLR.
Reference: http://support.microsoft.com/kb/922672