3

在我的 WCF 服务中,我正在使用Command.ExecuteReader()方法从 SQL 服务器检索数据。数据大小非常大(大约 1+ GB)并且通过 netTcp 绑定将此数据传输到客户端。

我打算在 WCF 中实现流模式而不是缓冲模式。任何人都可以将我指向任何文章或文件来做同样的事情。

简而言之,我的目标是将 IDataReader 转换为将传输到客户端和客户端的流对象,希望将此流转换回数据集/数据表或任何可以与 Grid 绑定的东西。

我无法将 IdataReader 转换为 IEnumerable,因为数据来自 SP,并且输出集中的列数不断变化(我不想在代码中添加列数限制)。

最终,将在数据集上完成从 WCF 服务到客户端应用程序的最终通信。如果任何解决方案,如将数据集转换为流,将其发送到客户端并在客户端,将流转换回数据集也将解决我的问题。

4

2 回答 2

1

您不应该尝试将 IDataReader 转换为流,而是让您的数据访问方法返回一个表示单行查询结果的类型的 IEnumerable,如下所示:

public IEnumerable<Order> GetOrders()
{
   IDbCommand cmd = ...  <<build your command here>> ...
   using(var rdr = cmd.ExecuteDataReader())
   {
      while(rdr.Read())
      {
          Order order = new Order {Id=rdr.GetDecimal(1), Name=rdr.GetString(2)};
          yield return order;
      }
   }
}

接下来,您可以将此方法的结果序列化为流(例如,@Mohamed 所示)。这样,您可以将对象列表发送到客户端,而无需将完整的结果集加载到内存中。当阅读器到达结果的末尾时,您仍然可以确定 datareader 已被释放。

于 2016-11-21T15:06:02.030 回答
1

您可以像这样将任何内容转换为流式传输:

var stream = new MemoryStream(Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(datareader)));

但这不是最佳实践。您应该使用数据读取器创建一个对象数组,然后将其返回。

于 2016-11-21T11:11:53.873 回答