2

我正在尝试从 WCF 服务获取数据并将其显示在网站中。
通信如下所示:
网站 --> WCF 服务 --> CRM 服务器 --> WCF 服务 --> 网站

现在我的问题是,有时需要获取更大的数据,大约 5k 行。(并且我的主机 PC 用完了 Ram)我想将 1-10 行流式传输到网站,然后是下一个,依此类推。

我的 ServiceContract 看起来像这样:

public interface ICommunicationService
{    
    [OperationContract]
    IEnumerable<Row> GetCrmData(string view);

}

而我的实现:

public IEnumerable<Row> GetCrmData(string view)
{
    var data = new DataFromCrm(view);
    return data.GetRows(MetaInformation);
}

GetRows 方法看起来完全像这样: http: //msdn.microsoft.com/en-us/library/gg327917.aspx 除了在 foreach 中我正在填充 Row 类并返回结果。(分页和烹饪被禁用atm)。

foreach (var c in returnCollection.Entities)
{
    var row = new Row();
    row.RecordId = c.Attributes[ID].ToString();
    foreach (var info in metaInfo)
    {
        row.Cells.Add(c.Attributes[info.AttributeName]);
    }
    yield return row;
}

1、收益回报用对了吗?

绑定
WCF 服务:

<behaviors>
  <serviceBehaviors>
    <behavior name="ServiceBehavior">
      <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="true" />
    </behavior>
  </serviceBehaviors>
</behaviors>

<services>
  <service behaviorConfiguration="ServiceBehavior" 
           name="ComToCrmService.CommunicationService">
    <endpoint binding="basicHttpBinding" 
              bindingNamespace="http://localhost:9006/CommunicationService.svc" 
              contract="ComToCrmContracts.ICommunicationService" />
  </service>
</services>

WCF 客户端

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_ICommunicationService" 
                 closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" 
                 bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
                 maxBufferSize="65536" 
                 maxReceivedMessageSize="4294967294" 
                 messageEncoding="Text" 
                 textEncoding="utf-8" 
                 transferMode="Streamed" 
                 useDefaultWebProxy="true">
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint binding="basicHttpBinding" 
                bindingConfiguration="BasicHttpBinding_ICommunicationService" 
                contract="ComToCrmReference.ICommunicationService" 
                name="BasicHttpBinding_ICommunicationService"
                address="http://dev11.meta10.com:9007/WCFTestService/CommunicationService.svc" />
    </client>
  </system.serviceModel>

2.绑定是否正确?

3、我的思维有问题吗?请记住,我试图在网站上显示 5000 行中的 1-10 行,然后获取接下来的 1-10 行,依此类推。
只有数据没有二进制数据或类似的东西。

4.一个请求就可以吗?

4

1 回答 1

6

首先,请记住 WCF 存在于面向服务的范式中,而不是面向对象的范式中。围绕 WCF 的许多误解在于它能够包装服务调用并以面向对象的方式呈现它。

您能够IEnumerable<Row>从服务中返回 a 的事实就是一个例子。我们误以为我们正在对抽象进行编程,而实际上 WCF 必须通过网络对服务调用的结果进行序列化(非常具体的实现),然后将其转换为客户端上的接口.

因此,您无法对您需要的序列执行“惰性”评估 - 是的 - 即使您只想要前 10 个,您也会将整个结果集拉过网络。

WCF 确实支持流式传输 ( http://msdn.microsoft.com/en-us/library/ms733742.aspx ),但更简单的方法可能是向您的服务合同添加参数以指示您需要的页面信息:

public interface ICommunicationService
{
    [OperationContract]
    Row[] GetCrmData(string view, int pageNumber, int pageSize);
}

这个契约更符合无状态的面向服务的应用程序,尊重你不应该在你的系统中传递大量数据,而只使用你需要的东西的概念。

请注意,我已将 替换为IEnumerable<Row>数组 - 消除了您正在通过线路对接口进行编程的印象。

于 2013-08-28T14:30:03.353 回答