增补透视一文:将 ADO.NET 或 Webservice返回 的 DataSet 转换成 ADODB.Recordset
小气的神 2001-10-23
记得在《透视和调整你的企业和商务系统》一文中,我们讨论了有关组件、 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 时我们是这样封装的:
1<webmethod()> Public Function GetAuthors() As DataSet
2
3Dim obj As bus_Authors.Authors
4
5Dim rst As ADODB.Recordset
6
7Dim myDataAdapter As OleDb.OleDbDataAdapter
8
9Dim retDataset As DataSet
10
11obj = New bus_Authors.Authors()
12
13rst = New ADODB.Recordset()
14
15myDataAdapter = New OleDb.OleDbDataAdapter()
16
17retDataset = New DataSet()
18
19rst = obj.GetAuthors()
20
21myDataAdapter.Fill(retDataset, rst, "GetAuthors" )
22
23GetAuthors = retDataset
24
25End Function
26
27而对于 VB 来说 RetXML 将是不可以认识和直接使用的,好在 Dataset 是基于 XML 的,事实上它是有规律的,我们可以通过直接访问 .asmx 文件( http://Dereksvr/Authors/Authors.asmx )来在网页上调用这个 WebService 的 GetAuthors() ,在 IE 中我们可以看到这个 Dataset 的结构,这样我们就可以找出规律,来使用这个 Dataset 中的数据。
28
29
30
31根据上面的情况我写了一个函数可以将 Dataset 转换成 ADODB.Recordset
32
33Public Function ConvDatasetToRecordset(ByVal voNL As IXMLDOMNodeList, ByVal vsTableName As String) As ADODB.Recordset
34
35Dim iXMLTableNode As IXMLDOMNode
36
37Dim iXMLRecordNode As IXMLDOMNode
38
39Dim iXMLFieldNode As IXMLDOMNode
40
41Dim iXMLNodeList As IXMLDOMNodeList
42
43Dim retRS As ADODB.Recordset
44
45Dim sXPath As String
46
47On Error GoTo ErrHandle
48
49' Create Recordset using the xsd schema
50
51sXPath = "//xsd:element[@name=""" & vsTableName & """]/xsd:complexType/xsd:sequence"
52
53Set iXMLTableNode = voNL.Item(1).selectSingleNode(sXPath)
54
55Set retRS = New ADODB.Recordset
56
57For Each iXMLFieldNode In iXMLTableNode.childNodes
58
59If Not iXMLFieldNode.Attributes Is Nothing Then
60
61Call retRS.Fields.Append(iXMLFieldNode.Attributes(0).Text, GetDataType(iXMLFieldNode.Attributes(1).Text), 512)
62
63End If
64
65Next
66
67' Add the data to the Recordset
68
69sXPath = "//" & vsTableName
70
71Set iXMLNodeList = voNL.Item(3).selectNodes(sXPath)
72
73Call retRS.Open
74
75For Each iXMLRecordNode In iXMLNodeList
76
77Call retRS.AddNew
78
79For Each iXMLFieldNode In iXMLRecordNode.childNodes
80
81If Len(iXMLFieldNode.baseName) > 0 Then
82
83retRS.Fields(iXMLFieldNode.baseName) = iXMLFieldNode.Text
84
85End If
86
87Next
88
89Next
90
91If Not (retRS.BOF And retRS.EOF) Then Call retRS.MoveFirst
92
93Set ConvDatasetToRecordset = retRS
94
95ErrExit:
96
97Exit Function
98
99ErrHandle:
100
101Set ConvDatasetToRecordset = Nothing
102
103Resume ErrExit
104
105End Function
106
107Private Function GetDataType(ByVal vsType As String) As ADODB.DataTypeEnum
108
109' Convert the XSD datatype to a ADO datatype
110
111Select Case vsType
112
113Case "xsd:string"
114
115GetDataType = adVarChar
116
117Case "xsd:int"
118
119GetDataType = adInteger
120
121Case "xsd:dateTime"
122
123GetDataType = adDate
124
125Case "xsd:decimal"
126
127GetDataType = adDouble
128
129Case "xsd:boolean"
130
131GetDataType = adBoolean
132
133End Select
134
135End Function
136
137对于 GetDataType 中的类型我没有一一试过,只使用了常见的几个,具体的可以参见下面的链接:
138
139http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk30/htm/xmrefsupporteddatatypeconversions.asp
140
141http://msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdcstdatatypeenum.asp
142
143继续添加,以保证能够符合你具体的需要。然后套用我们在第三篇中的表现层的函数显示在一个 Grid 中 :
144
145Set RetXML = SoapClient.GetAuthors()
146
147Set result = ConvDatasetToRecordset (RetXML, “GetAuthors”)
148
149LvwHeadName lstAuthors, strHeaders
150
151ADOFillLvw result, lstAuthors
152
153想想挺有意思,开始是 ADODB.Recordset 类型的,然后在 WebService 中转换成 DataSet 类型,然后又转换成 ADODB.Recordset 。 XML 是一个强大的介质,而 dotNET 中对于 Dataset 比上一版的 Recordset 也将是一种突破。对于 DataSet 的应用也将是极其灵活和没有限制的,因为它的核心和基础是 XML 。
154
155既然是增补,我也应要求将透视和调整一文中涉及到的例子的 Project 和代码上载到 CSDN ,另外一个是拷屏的图片,希望两者对于阅读和理解会有少许帮助,具体的安装过程我就省略了。
156
157相关文件:
158
159http://263.csdn.net/FileBBS/files/2001_10/T_724_1.zip(Code )
160
161http://263.csdn.net/FileBBS/files/2001_10/T_724_2.zip(Jpg )
162
163
164* * *
165
166特别:
167
168以上文字和图片涉及其他人的隐私和个人权利,如非被授权或经本人同意,任何网站或期刊请不要刊登、转载、改编、转贴或已其他形式进行传播。以上所有文字和图片只用于内部交流,不作任何新闻发表和商业用途。</webmethod()>