IQueryable проблемы с использованием WCF - PullRequest
7 голосов
/ 27 июля 2010

У меня есть довольно простой метод службы WCF, который возвращает IQueryable, только для тестирования. Возможно, я что-то не так понял, пытаясь понять, для чего предназначен IQueryable. Я определенно планирую использовать это с поставщиком IQueryable NHibernate позже. Но сначала я столкнулся с какими-то проблемами сериализации (по крайней мере, я думаю, что это может быть проблемой) всякий раз, когда используется метод WCF, возвращающий IQueryable. Это даже не работает для простой строки.

Вот мой код:

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

Это может не иметь особого смысла, это просто для проверки, действительно ли я получаю эти IQueryables по проводам, используя WCF. Всякий раз, когда я вызываю этот метод с использованием клиента, такого как SoapUI, я получаю исключение сокета и сброс соединения, точно так же, как если бы я пытался вернуть что-то, что не помечено как DataContract. Но единственное, что я здесь делаю, это пытаюсь вернуть какой-то паршивый список строк. Что в этом плохого?

Я использую BasicHTTPBinding, вот мои настройки:

<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>

Атрибут OperationContract установлен для интерфейса:

[OperationContract]
IQueryable<string> GetEquipmentConfigurations();

Все это хорошо работает, когда просто возвращаешь простую строку. В любом случае, я хочу извлечь выгоду из функций IQueryable, используя LINQ позже.

Кто-нибудь знает, что здесь происходит не так?

Спасибо и ура,

Stefan

Ответы [ 2 ]

10 голосов
/ 27 июля 2010

Основной WCF предназначен для отправки данных , а не запросов.Придерживайтесь возврата List<Foo> и т. Д .;это избавит вас от головокружения.

Однако вам, возможно, повезет больше с тем, что вам нужно, с WCF Data Services , что позволяет вам открывать IQueryable<> источники.

Способ, которым это работает, состоит в том, что инструментарий создает клиента, который предоставляет аналогичные IQueryable<> хуки;когда вы запрашиваете данные, оно представляет выражение в сети, запрашивает данные и возвращает их клиенту.Но это все еще результаты (не запрос), который идет по проводу.

5 голосов
/ 27 июля 2010

(Устаревшая) На самом деле, из коробки невозможно сериализовать IQueryable <> или деревья выражений (подумайте об этом - это будет означать, что дерево выражений / лямбда-выражения необходимо будет сериализовать и перестроить функцию)

Однако там, где есть желание, кажется, что есть выход - вы можете захотеть взглянуть на такие проекты, как этот http://code.msdn.microsoft.com/exprserialization

Редактировать : обратите внимание, что времена изменились - см. Службы RIA WCF согласно посту Марка Гравелла.

Удачи!

НТН

...