Как конвертировать IDataReader в поток в C#
В моей службе WCF я получаю данные с сервера SQL, используя Command.ExecuteReader()
метод. Размер данных очень большой (около 1+ ГБ) и передает эти данные клиенту через привязку netTcp.
Я планирую реализовать потоковый режим вместо буферизованного режима в WCF. Может кто-нибудь указать мне на любую статью или документ, чтобы сделать то же самое.
Проще говоря, моя цель - преобразовать IDataReader в потоковый объект, который будет передаваться на клиентскую и клиентскую стороны, хотите преобразовать этот поток обратно в набор данных / datatable или все, что может быть связано с Grid.
Я не могу преобразовать IdataReader в IEnumerable, так как данные поступают через SP, и ни один из столбцов в выходном наборе не меняется (я не хочу добавлять ограничение кода в коде).
В конечном счете, окончательный обмен данными будет осуществляться по набору данных от службы WCF к клиентскому приложению. Если какое-либо решение, такое как преобразование набора данных в поток, отправка его клиенту и клиенту, преобразование потока обратно в набор данных также решит мою проблему.
2 ответа
Вы не должны пытаться преобразовать 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). Таким образом, вы можете отправить список объектов клиенту без необходимости загрузки полного набора результатов в память. И вы по-прежнему уверены, что устройство чтения данных удаляется, когда читатель достиг конца результата.
Вы можете преобразовать что угодно в поток, как это:
var stream = new MemoryStream(Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(datareader)));
но это не лучшая практика. Вы должны создать массив объектов с вашим устройством чтения данных, а затем вернуть его.