Я пишу консольное приложение, которое должно копировать большие таблицы SQL из одной базы данных в другую, отправляя данные через веб-службу. Поскольку таблицы могут быть очень большими и поскольку они не могут (и не должны) полностью храниться в памяти, я использую DataReader для последовательного чтения данных и надеялся передать их в веб-службу.
Для этого я объявил свой веб-сервис следующим образом:
<OperationContract()>
<WebInvoke(UriTemplate:="{Id}/SendData", method:="PUT", BodyStyle:=WebMessageBodyStyle.WrappedRequest)>
Sub UploadData(ByVal Id As String, ByVal DataStream As Stream)
В моем консольном приложении я создаю запрос следующим образом:
Dim tRequest As HttpWebRequest = HttpWebRequest.Create(URL_WEBSERVICES & "DataLoad/" & _Id & "/SendData")
tRequest.SendChunked = True
tRequest.Method = "PUT"
tRequest.ContentType = "application/octet-stream"
Затем я открываю поток запросов и записываю данные так:
While tSqlReader.Read
' Check if a new chunk of data must be created
If tRows Is Nothing Then
tRows = New List(Of Object)
End If
' Fill chunk with data
tRowValues = New Object(tSqlReader.FieldCount - 1) {}
tSqlReader.GetValues(tRowValues)
tRows.Add(tRowValues)
' Check if chunk is full and must be sent
If tRows.Count = CHUNK_ROWS_COUNT Then
' Write data to the request stream
tDataChunk = SerializeToByteArray(tRows)
tStream.Write(tDataChunk, 0, tDataChunk.Length)
tRows = Nothing
tDataChunk = Nothing
End If
End While
' Write final data to the request stream
If tRows IsNot Nothing Then
tDataChunk = SerializeToByteArray(tRows)
tStream.Write(tDataChunk, 0, tDataChunk.Length)
End If
Затем я закрываю поток запросов и вызываю tRequest.GetResponse().
SerializeToByArray — это следующая функция:
Private Function SerializeToByteArray(ByVal pObject As Object) As Byte()
If pObject Is Nothing Then Return Nothing
Dim tBinaryFormatter As New Runtime.Serialization.Formatters.Binary.BinaryFormatter
Dim tMemoryStream As New MemoryStream()
tBinaryFormatter.Serialize(tMemoryStream, pObject)
Return tMemoryStream.ToArray
End Function
Моя проблема в том, что веб-служба получает только первый фрагмент данных, например. если CHUNK_ROWS_COUNT = 5, то он получает только 5 строк данных. (Я знаю, что это не размер фрагментов, которые сделает HttpWebRequest).
Мое единственное предположение состоит в том, что я отправляю несколько сериализованных пакетов данных через поток, каждый из которых инкапсулирован некоторыми заголовками сериализации, и поэтому процесс десериализации в веб-службе находит и декапсулирует только первый, но это всего лишь идея, и я не уверен, как сделать это по-другому. Я не могу сериализовать весь контент и отправить его на запись по частям, потому что весь контент не помещается в памяти.
Любой совет?
Заранее большое спасибо