понедельник, 9 марта 2009 г.

WCF: Как переслать ADODB.Recordset


К сожалению пересылка ADODB.Recordset используя WCF не столь тривиальна, как пересылка многих других объектов .Net. Дело в том, что ADODB.Recordset не сериализуем (serializable). Следующий код призван решить данную проблему.

1. Без сериализации используя xml, т.е. не увеличивая поток данных внутри WCF message.

2. Без использования DataTable - если ваш код в последствии использует ADODB.Recordset (например вы передаёте данный объект какому-то старому коду наследованном со времён когда .Net ещё не было) - так как конвертация DataTable в ADODB.Recordset достаточно затратная с точки зрения производительности и времени операция.

Ниже приводимый пример написан на VB.Net. Тоже самое легко написать, например, на C# следую основной канве представленной в примере.


'Предположим rs это ADODB.Recordset уже существующий в вашем коде.

Dim ret() As Byte
Dim aStr As Object = CreateObject("ADODB.Stream")

rs.Save(aStr, 0) ' 0 эквивалентно ADODB.PersistFormatEnum.adPersistADTG)
Return aStr.Read(aStr.Size)

Dim binFormat = New System.Runtime.Serialization.Formatters.Binary.BinaryFormatter()

Dim oStream As New System.IO.MemoryStream()
binFormat.Serialize(oStream, rs)
oStream.Flush()
oStream.Position = 0

ret = oStream.ToArray() ' Теперь вы можете передать ret используя WCF


На стороне клиента для конвертирования обратно в ADODB.Recordset можно использовать следующий код. Представим, что QueryBypassAsByte - это функция которая передаёт наш byte array используя WCF вызов


Dim res() As Byte = proxy.QueryBypassAsByte()
Dim oStr As New ADODB.Stream()

'' прочитать в ADODB.Stream...
oStr.Open(System.Reflection.Missing.Value, ADODB.ConnectModeEnum.adModeUnknown, ADODB.StreamOpenOptionsEnum.adOpenStreamUnspecified, "", "")
oStr.Type = ADODB.StreamTypeEnum.adTypeBinary
oStr.Write(res)
oStr.Position = 0

Dim resRecordset As New ADODB.Recordset()
resRecordset.Open(oStr, System.Reflection.Missing.Value, ADODB.CursorTypeEnum.adOpenStatic, ADODB.LockTypeEnum.adLockReadOnly, -1)


Теперь объект resRecordset содержит ADODB.Recordset и вы можете использовать его по своему усмотрению в вашем коде.

Комментариев нет: