如何在C#中将IDataReader转换为Stream#

时间:2016-11-21 11:00:13

标签: wcf c#-4.0 stream idatareader executereader

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

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

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

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

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

2 个答案:

答案 0 :(得分:1)

你可以将任何东西转换为像这样的流:

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

但这不是最佳做法。您应该使用datareader创建一个对象数组,然后将其返回。

答案 1 :(得分: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所示)。这样,您可以将对象列表发送到客户端,而无需将完整的结果集加载到内存中。当读者到达结果的末尾时,您仍然确定数据处理器已被处理。