IQueryable problems using WCF

2019-02-17 00:02发布

问题:

I have a quite simple WCF service method which returns an IQueryable, just for testing. Perhaps I got something wrong when trying to understand what IQueryable is designed for. I clearly plan to use this with the IQueryable provider of NHibernate later. But first I ran into some sort of serialization problems (at least I think it might be the problem) whenever using a WCF method returning an IQueryable. It doesn't even work for a simple string.

Here's my code:

public IQueryable<string> GetEquipmentConfigurations()
{
  var returnValue = new List<string>();
  returnValue.Add("test");
  return returnValue.AsQueryable();
}

It might not have much sense, it's just for testing whether I really get those IQueryables over the wire using WCF. Whenever I call this method using a client like SoapUI I get a socket exception and a connection reset, just the same as if I was trying to return something that is not marked as DataContract. But the only thing I do here is trying to return some lousy string list. What's wrong with that?

I use basicHTTPBinding, here are my settings:

<system.serviceModel>
   <services>
      <service name="EquipmentConfigurationService" behaviorConfiguration="DefaultBehavior">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8000/Krones.KBase/Services/EquipmentConfigurationService"/>
          </baseAddresses>
        </host>
        <endpoint address=""
                  binding="basicHttpBinding"
                  contract="Krones.MES.KBase.Public.Service.EquipmentDefinition.IEquipmentConfigurationService" />
        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
      </service>
   </services>
   <behaviors>
      <serviceBehaviors>
         <behavior name="DefaultBehavior">
            <serviceMetadata httpGetEnabled="True"/>
            <serviceDebug includeExceptionDetailInFaults="True"/>
         </behavior>
      </serviceBehaviors>
   </behaviors>
</system.serviceModel>

The OperationContract attribute is set for the interface:

[OperationContract]
IQueryable<string> GetEquipmentConfigurations();

It all works well when just returning a simple string. Anyway I want to take profit from the IQueryable features using LINQ later.

Anybody any idea what's going wrong here?

Thanks and Cheers,

Stefan

回答1:

(Obsolete) AFAIK it isn't possible out of the box to serialize IQueryable<> or Expression Trees (think about it - it would mean that the expression tree / lambda would need to be serialized and the function rebuilt)

However, where there is a will, it seems there is a way - you might want to look at projects such as this http://code.msdn.microsoft.com/exprserialization

Edit : Note that times have changed - See WCF RIA Services as per Marc Gravell's post.

Good luck!

HTH



回答2:

The core WCF is designed to send data, not queries. Stick to returning List<Foo> etc; it'll save you much head-scratching.

However, you might have more luck doing what you are after with WCF Data Services, which allows you to expose IQueryable<> sources.

The way this works is that the tooling builds a client that exposes similar looking IQueryable<> hooks; when you query data, it represents the expression on the wire, queries the data and brings it back to the client. But it is still the results (not the query) that goes over the wire.