Custom marshalling of ADO.NET dataset to ADO Recordset



Hi

I hope someone can help with this - bit of a complicated problem.

Our existing system is a COM based windows client, written in VB. There is a
requirement for a server based solution and I have elected to use .NET, using
Remoting for the communication between client and server and COM interop to
bridge the VB6 client and .NET assemblies.

In future, we hope to migrate our windows client to .NET but do not have the
time or resource to do so at present.

The problem is that I would like to use the .NET infrastructure and
framework as far as possible, in particular using datasets and ADO.NET for
data access. The problem comes when passing data back to the VB6 client.

The client contains many screens hosting a 3rd party grid control, this
expects a recordset. I have tried the simple approach of dynamically creating
a recordset from a dataset (iterating through all rows in the dataset and
adding to a disconnected recordset) but this takes far too long for a dataset
containing large amounts of data.

I came across this article
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/cominterop.asp, in particular the section:

"Another option is to write .NET custom marshaling code that automatically
translates between a dataset and a recordset when a dataset is returned as a
parameter. This is the most elegant solution and is transparent to the
implementers of the business code in both tiers. "

I have created a custom marshaler in an attempt to convert the dataset to a
recorset but cannot get VB6 to recognize the type as a recordset. I use the
GUID attribute to type my implementation of a recordset as an ADODB.Recordset.

i.e.

<ComImport(), Guid("00000556-0000-0010-8000-00AA006D2EA4"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Public Interface IMyRecordset
Sub Open(Optional ByVal Source As Object = Nothing, Optional ByVal
ActiveConnection As Object = Nothing, Optional ByVal CursorType As
ADODB.CursorTypeEnum = ADODB.CursorTypeEnum.adOpenUnspecified, Optional ByVal
LockType As ADODB.LockTypeEnum = ADODB.LockTypeEnum.adLockUnspecified,
Optional ByVal Options As Integer = -1)
Sub Close()
Function GetRows(Optional ByVal Rows As Integer = -1, Optional ByVal
Start As Object = Nothing, Optional ByVal Fields As Object = Nothing) As
Object
Property MaxRecords() As Integer
Sub Move(ByVal NumRecords As Integer, Optional ByVal Start As Object =
Nothing)
Sub MoveFirst()
Sub MoveLast()
Sub MoveNext()
Sub MovePrevious()
ReadOnly Property RecordCount() As Integer
Sub Requery(Optional ByVal Options As Integer = -1)
Sub Resync(Optional ByVal AffectRecords As ADODB.AffectEnum =
ADODB.AffectEnum.adAffectAll, Optional ByVal ResyncValues As ADODB.ResyncEnum
= ADODB.ResyncEnum.adResyncAllValues)
Sub Seek(ByVal KeyValues As Object, Optional ByVal SeekOption As
ADODB.SeekEnum = ADODB.SeekEnum.adSeekFirstEQ)
Property Sort() As String
ReadOnly Property State() As Integer
ReadOnly Property Status() As Integer
Sub Update(Optional ByVal Fields As Object = Nothing, Optional ByVal
Values As Object = Nothing)
ReadOnly Property Fields() As ADODB.Fields
Property DataMember() As String
Sub AddNew(Optional ByVal FieldList As Object = Nothing, Optional ByVal
Values As Object = Nothing)
ReadOnly Property BOF() As Boolean
ReadOnly Property EOF() As Boolean
ReadOnly Property DataSource() As Object
End Interface

<ProgId("ADODB.Recordset")> _
Public Class MyRecordset
Implements IMyRecordset
..... etc


The VB program notes the type as MyRecordset and I can access methods,
properties, etc. but the databind on the 3rd party control has no effect -
presumably as it is not the correct type.

I would be very grateful for any help - even if it's to tell me I'm wasting
my time trying to get this to work.

Best regards

Wayne
.



Relevant Pages