-
增补透视一文:将ADO.NET或Webservice返回的DataSet转换成ADODB.Recordset
记得在《透视和调整你的企业和商务系统》一文中,我们讨论了有关组件、SOAP、WebService的一些问题,特别对于这样的一些问题: 如何生成一个构造一个简单的三层结构(Window DNA) 如何将现有的组件暴露出来,成为一个WebService 如何使用MS SOAP Toolkit来生成Client消费WebService 如何在dotNET中调用SOAP Toolkit生成的WebService 如何处理和传输ADODB.Recordset类型的数据,实现自己的CTM。 如何将目前的组件用ASP.NET封装成WebService 进行了一些讨论和实验,在讨论到用ASP.NET封装我们的组件成WebService,然后使用MS SOAP Toolkit消费WebService时,我曾跳过了一个问题,那就是如何接收WebService传输过来的成组数据。 记得代码是这样的: Dim RetXML as Object Dim SoapClient As MSSOAPLib.SoapClient Set SoapClient = New MSSOAPLib.SoapClient Call SoapClient.mssoapinit("http://Dereksvr/Authors/Authors.asmx?WSDL") Set RetXML = SoapClient.GetAuthors() GetAuthors()返回的是一个DataSet类型,在开始生成WebService时我们是这样封装的: <WebMethod()> Public Function GetAuthors() As DataSet Dim obj As bus_Authors.Authors Dim rst As ADODB.Recordset Dim myDataAdapter As OleDb.OleDbDataAdapter Dim retDataset As DataSet obj = New bus_Authors.Authors() rst = New ADODB.Recordset() myDataAdapter = New OleDb.OleDbDataAdapter() retDataset = New DataSet() rst = obj.GetAuthors() myDataAdapter.Fill(retDataset,rst,"GetAuthors") GetAuthors = retDataset End Function 而对于VB来说RetXML将是不可以认识和直接使用的,好在Dataset是基于XML的,事实上它是有规律的,我们可以通过直接访问.asmx文件(http://Dereksvr/Authors/Authors.asmx)来在网页上调用这个WebService 的GetAuthors(),在IE中我们可以看到这个Dataset的结构,这样我们就可以找出规律,来使用这个Dataset中的数据。 根据上面的情况我写了一个函数可以将Dataset转换成ADODB.Recordset Public Function ConvDatasetToRecordset(ByVal voNL As IXMLDOMNodeList,ByVal vsTableName As String) As ADODB.Recordset Dim iXMLTableNode As IXMLDOMNode Dim iXMLRecordNode As IXMLDOMNode Dim iXMLFieldNode As IXMLDOMNode Dim iXMLNodeList As IXMLDOMNodeList Dim retRS As ADODB.Recordset Dim sXPath As String On Error GoTo ErrHandle ' Create Recordset using the xsd schema sXPath = "//xsd:element[@name=""" & vsTableName & """]/xsd:complexType/xsd:sequence" Set iXMLTableNode = voNL.Item(1).selectSingleNode(sXPath) Set retRS = New ADODB.Recordset For Each iXMLFieldNode In iXMLTableNode.childNodes If Not iXMLFieldNode.Attributes Is Nothing Then Call retRS.Fields.Append(iXMLFieldNode.Attributes(0).Text,GetDataType(iXMLFieldNode.Attributes(1).Text),512) End If Next ' Add the data to the Recordset sXPath = "//" & vsTableName Set iXMLNodeList = voNL.Item(3).selectNodes(sXPath) Call retRS.Open For Each iXMLRecordNode In iXMLNodeList Call retRS.AddNew For Each iXMLFieldNode In iXMLRecordNode.childNodes If Len(iXMLFieldNode.baseName) > 0 Then retRS.Fields(iXMLFieldNode.baseName) = iXMLFieldNode.Text End If Next Next If Not (retRS.BOF And retRS.EOF) Then Call retRS.MoveFirst Set ConvDatasetToRecordset = retRS ErrExit: Exit Function ErrHandle: Set ConvDatasetToRecordset = Nothing Resume ErrExit End Function Private Function GetDataType(ByVal vsType As String) As ADODB.DataTypeEnum ' Convert the XSD datatype to a ADO datatype Select Case vsType Case "xsd:string" GetDataType = adVarChar Case "xsd:int" GetDataType = adInteger Case "xsd:dateTime" GetDataType = adDate Case "xsd:decimal" GetDataType = adDouble Case "xsd:boolean" GetDataType = adBoolean End Select End Function 对于GetDataType中的类型我没有一一试过,只使用了常见的几个,具体的可以参见下面的链接: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk30/htm/xmrefsupporteddatatypeconversions.asp http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdcstdatatypeenum.asp 继续添加,以保证能够符合你具体的需要。然后套用我们在第三篇中的表现层的函数显示在一个Grid中: Set RetXML = SoapClient.GetAuthors() Set result = ConvDatasetToRecordset(RetXML,“GetAuthors”) LvwHeadName lstAuthors,strHeaders ADOFillLvw result,lstAuthors 想想挺有意思,开始是ADODB.Recordset类型的,然后在WebService中转换成DataSet类型,然后又转换成ADODB.Recordset。XML是一个强大的介质,而dotNET中对于Dataset比上一版的Recordset也将是一种突破。对于DataSet的应用也将是极其灵活和没有限制的,因为它的核心和基础是XML。 既然是增补,我也应要求将透视和调整一文中涉及到的例子的Project和代码上载到CSDN,另外一个是拷屏的图片,希望两者对于阅读和理解会有少许帮助,具体的安装过程我就省略了。 相关文件: http://263.csdn.net/FileBBS/files/2001_10/T_724_1.zip(Code) http://263.csdn.net/FileBBS/files/2001_10/T_724_2.zip(Jpg)