Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ADODB.Stream and Marshalling

0 views
Skip to first unread message

Mike Housey

unread,
Oct 18, 2001, 4:55:16 PM10/18/01
to
I am attempting to expriment with using xml stream to pass
data from the middle tier to a client. I have the middle
tier creating a recordset and then saving it to a
adodb.stream object. When I run the program on the same
machine the stream is saved, passed to the client app
which then opens a recordset up using the stream as a
source. It works fine. However, when obtaining the
stream object from a component on another computer I
get "Arguments are of the wrong type, are out of
acceptable range, or are in conflict with one another."
when trying to open the recordset. All properties of the
stream object are identical regardless if called locally
or on the application server. I went to the application
server and called the component locally, and it also
worked fine. It seems there is a problem with the
marshalling. Below is the code:

'//st is a ADODB.Stream which is returned successfully
weather called remotely or locally...

Set st = obj.GetDataAsXMLStream
(s, "DSN=SOIDEV;UID=olesvr;PWD=olesvr")

'// this call works if obj is local, fails if remote ?!?
rs.Open st

Any help would be greatly appreciated !

Ted McNeal

unread,
Oct 18, 2001, 5:09:14 PM10/18/01
to
Mike,

You cannot marshal the stream object.

You should dehydrate the recordset to a string as XDR then marshal the
string.

Then you can rehydrate the XDR string back to an ADO recordset object.

Also, you can marshal the ADO recordset object itself.

Below is a couple of helper functions that I wrote to hydrate and dehydrate
recordsets.

Private Const MODULE_NAME As String = "basYourModuleName"

Public Function DehydrateRecordset(ByRef rst As ADODB.Recordset) As String
Dim stm As ADODB.Stream
On Error GoTo Proc_Err

If rst.State = ADODB.adStateClosed Then
Err.Raise vbObjectError + 512, "DehydrateRecordset", "The recordset
passed must be open."
End If

Set stm = New ADODB.Stream
rst.Save stm, adPersistXML
stm.Position = 0
DehydrateRecordset = stm.ReadText()

Proc_Exit:
On Error Resume Next
stm.Close
Set stm = Nothing
Exit Function

Proc_Err:
Err.Raise Err.Number, Err.Source & ", " & MODULE_NAME &
".DehydrateRecordset", Err.Description
Resume Proc_Exit
End Function

Public Function HydrateRecordset(ByVal strXDR As String) As ADODB.Recordset
Dim stm As ADODB.Stream
On Error GoTo Proc_Err

If Len(strXDR) = 0 Then
Err.Raise vbObjectError + 512, "HydrateRecordset", "An XDR dataset was
not supplied."
End If

Set stm = New ADODB.Stream
With stm
.Open
.WriteText strXDR
.Position = 0
End With
Set HydrateRecordset = New ADODB.Recordset
HydrateRecordset.Open stm

Proc_Exit:
On Error Resume Next
stm.Close
Set stm = Nothing
Exit Function

Proc_Err:
Err.Raise Err.Number, Err.Source & ", " & MODULE_NAME & ".HydrateRecordset",
Err.Description
Resume Proc_Exit
End Function

HTH,

Ted McNeal

"Mike Housey" <hm...@housey.net> wrote in message
news:06ed01c15817$3079b820$9ae62ecf@tkmsftngxa02...

Mike Housey

unread,
Oct 18, 2001, 5:04:44 PM10/18/01
to

Mike Housey

unread,
Oct 22, 2001, 2:19:08 PM10/22/01
to
Thanks Ted ! Your hydrate and dehydrate functions work
quite well. When compared against marshalling recordsets,
the xml string method is actually faster for small data
sets (< 1000 records). However, when comparing small data-
sets, neither disconnected recordsets or xml strings even
come close to passing data using variant arrays. I get
the feeling that Microsoft frowns upon this method. Can
anyone tell me an alternate method with the same
performance ?

Thanks in Advance !

Ted McNeal

unread,
Oct 22, 2001, 8:54:34 PM10/22/01
to
Mike,

Your welcome. I have some more comments that may be helpful with your
proofs.

Cached recordsets are stored in a format called ADTG (Advanced Table
Datagram). This is a proprietary binary format that is not legible like
XML/XDR. I believe this is the format that an ADO recordset is serialized
into when it is marshaled. It has a smaller footprint than XDR persisted
recordsets. Since you are using ORPC, there is less value in marshalling
XDR anyway unless you plan to expose your objects directly to HTTP clients
or want to use XSL against the resultsets w/o conversion. I prefer to use
XDR to keep my options open even though it may cost a little bit.

You may want to create different interfaces for each method employed. This
will allow you to easily provide a new implementations in the future or
switch to XDR if you choose to expose your objects to HTTP clients. For
example, my clsDataReader implements an interface for XDR clients called
IDataReaderXDR.

I don't think that variant arrays are frowned upon when using COM. The
safearray is a specified type in the COM specs and can marshal with very
good performance. It does very well with smaller sets because it does not
have metadata overhead. But, this information is very helpful to the other
tiers.

You can look at using a property bag object to serialize structures. This
is another method that may perform well but is not intended to be used in
this manner.

Take a look at the article called 'Optimizing Interactions Between the COM+
Business Logic Tier and the Presentation Tier' that is in the COM+ section
of the Platform SKD documentation (MSDN CD). It may be on the site as well.
It will provide a terse view of some of the options you are pondering.

-Ted McNeal


"Mike Housey" <hm...@housey.net> wrote in message

news:15fb01c15b26$0aa365d0$37ef2ecf@TKMSFTNGXA13...

0 new messages