zoukankan      html  css  js  c++  java
  • 选择正确的API从SQL Server获取XML数据

    选择正确的API从SQL Server获取XML数据。
    by Greg Ewing and Jon Rauschenberger
    技术工具箱: C#, SQL Server 2000, ASP.NET, XML, VB6

    .NET Framework包含几个新的数据存取APIs,每种API对访问SQL Server中XML数据的支持程度都不同。在如何完成你的解决方案、需要写多少代码方面,选择不同的API将会有不同的结果。在本专栏中,我将阐述Microsoft的四种XML数据存取APIs:ActiveX Data Objects (ADO) 2.6、ADO.NET、SqlDataReader和 SQLXML。

    我们将重点讲述实现每种API需要的代码,并比较每种API提供的性能和可扩展性。通过一步步构建查询一个Northwind数据库所需要的代码,将结果转化成XML,我们来逐个说明这些API。然后通过对它们进行一些负载测试,我们来看看它们的性能如何。

    要确定哪种XML数据存取API能够最好地满足你的需求,你需要考虑几个因素。首先,看一下每种API需要的代码量。然后,考虑你有多大的灵活性来控制API返回的XML格式。有时候,你不能控制XML的格式。最后,考虑API是如何执行和扩展的。因为SQL Server没有将本地数据存为XML,所以将数据从本地的SQL Server二进位格式转换成XML所需要的费用可能很高,可能会限制你的应用程序的性能和可扩展性

    ADO是一个受欢迎的数据存取API。Microsoft最初在ADO 2.1中增加了将结果集转换成XML的支持功能,这就使你可以将一个结果集存为一个XML文件。相对于ADO 2.6对XML有限的支持,ADO.NET增加了许多新的XML功能。ADO.NET DataSet对象支持将结果集串行化成格式规范的XML。

    让我们开始做个样例程序吧,打开VS.NET,创建一个新的C#类库。将Class1.cs重新命名为DBXml.cs,并取消名字空间。然后,添加引用System.Data.dll,它包含ADO.NET名字空间。接着,打开ADONet类并引入这些名字空间:

    using System.Data;
                using System.Data.SqlClient;
                

    现在,给DBXml 类添加代码,连接到数据库并用ADO.NET来执行SELECT语句(见列表1)。ExecuteSelect函数做的第一件事就是通过传递连接字符串到构造器用SqlConnection类来初试化一个到数据库的连接。然后,创建 SqlDataAdapter,将SELECT语句和连接对象传递到构造器中。SELECT语句有一个参数用于你选择的用户的ID,所以你必须将那个参数添加到SelectCommand Parameters集合中。Add函数可以接受参数的名字、数据类型、大小和列的关连。一旦这个参数是集合的一部分,你需要给它赋以正确的值。

    下面的两步,创建DataSet并用适配器填充它,完成了大部分工作。如果连接没有打开,用DataAdapter上的Fill方法来打开连接,或者用已打开的连接,它通常返回到最初的状态。然后,你用GetXML函数将DataSet转换成XML字符串,返回给调用者。

    运用SqlDataReader
    SqlDataReader为数据存取提供了一个连续的、只读的指针,使其成为从SQL Server读取数据的最快的方式。DataReader对XML没有提供本地的支持,所以你必须自己写XML转换代码或运行一个返回XML的查询过程。对于这个例子,你可以用FOR XML RAW子句让SQL Server返回XML的数据。

    运用SqlDataReader,写代码来执行SELECT语句并返回XML的结果(见列表2)。该方法中的第一行代码同ExecuteSelect函数一样。同DataSets一样,SqlDataReader依赖于一个SqlConnection对象。通过将SQL语句和Connection对象传递到构造器来创建Command对象。

    在打开数据库连接后,通过给SqlDataReader赋以Command.ExecuteReader方法的返回值来创建SqlDataReader。然后,用StringBuilder类从SqlDataReader读取XML。在处理大的字符串方面,StringBuilder类比String类的字符串处理方法更有效。

    调用 GetString(0)来得到与当前行的数据相关的字符串。结果集在一个很长的XML字符串中,所以你只需要反复调用read(),直到DataReader为空。一旦你创建了字符串,只需要把它返回给调用者就行了。

    运用VS.NET得到XML数据的最后一个方法就是通过运用SQLXML托管类,它们是SQLXML 3.0功能包的一部分(见资源)。SQLXML功能包扩展了SQL Server 2000的XML功能。3.0版本中的托管类是.NET Framework的本地类,它们可以使用新增加的XML功能。



    SQLXML 3.0的安装将Microsoft.Data.SqlXml集合装到你的机子上。给项目添加对该集合的一个引用,并用以下代码引入名字空间:

    using Microsoft.Data.SqlXml;
                

    以下代码连接到数据库,并用SQLXML类来执行SELECT语句:

    public string ExecuteSqlXmlSelect(
                string CustomerID,
                string ConnectionString,
                bool ClientSide)
                {
                SqlXmlCommand cmd = new
                SqlXmlCommand(ConnectionString);
                cmd.RootTag = "Employees";
                cmd.ClientSideXml = ClientSide;
                cmd.CommandText = "SELECT * FROM
                Customers WHERE CustomerID = '" +
                CustomerID + "' FOR XML RAW";
                XmlReader xr =
                cmd.ExecuteXmlReader();
                XmlDocument xd = new XmlDocument();
                xd.Load(xr);
                return xd.OuterXml;
                }
                

    该代码所做的第一件事就是通过将连接字符串传递到构造器来创建必要的SqlXmlCommand对象。由FOR XML创建的XML通常是一个XML片段,并不是格式规范的文件。为了使XML格式规范,你必须用RootTag属性在Command对象上设置一个根标签,在本例中设置成“employees”。

    SQLXML功能包的以前的版本在将XML返回给客户端前在数据库服务器上构造XML。这会造成可扩展性方面的问题,因为创建的XML没有分布给客户端,所以产生的XML流比默认情况下SQL Server返回的本地二进位数据流要大很多。3.0版本允许SQLXML将数据流作为二进位数据返回给客户端,然后在客户端上将数据转换成XML。

    将数据转换成XML
    将ClientSideXml属性设置成True来实现这一步。你仍然用带有FOR XML子句的SELECT语句,但是当你将ClientSideXml设置为True时,在将语句传送到SQL Server前,托管类将FOR XML子句从SQL语句中去掉了。数据库不再看到FOR XML子句,可以更有效地将数据流返回给客户端。然后,SQL托管类在客户端将数据流转换成XML。

    通过调用ExecuteXmlReader方法来执行SELECT语句,该方法返回一个XmlReader对象。然后,你将XmlReader对象载入一个XmlDocument,并将产生的OuterXml返回给调用者。

    最后一个数据存取API是运用ADO 2.6和Visual Basic 6.0。通过打开一个新的VB6 ActiveX DLL项目来创建这个项目。重新命名Class1为ADO26,命名项目为DBXMLVS6。然后,给项目添加ActiveX Data Objects 2.6引用。一旦完成这一步,就给你的类添加ExecuteSelect方法(见列表3)。

    同所有其它例子一样,你先要创建并打开你的数据库连接。然后,创建新的Command对象,并给Connection对象设置其ActiveConnection属性。SELECT语句同ADO.NET例子中用的SELECT语句一样。

    
				图1.
    图1. 看看哪种API最快
    将Execute方法的返回值设置给RecordSet对象。你需要创建一个ADO Stream对象将结果集转换成XML。将Stream的Type属性设置成adTypeText,并打开它。打开后,在你的结果集上调用Save方法,指明你想把结果集保存为XML。一旦XML在数据流中,用ReadText方法将它返回给调用者。

    通过创建简单的ASP和ASP.NET页面,调用组件并将XML返回给浏览器,我们就可以测试每种API实现的性能和可扩展性(在图1中可以看到结果,关于更详细的结果,请参考工具条“测试记录”。关于这些ASP和ASP.NET页面,请在此下载代码。)

    随着Microsoft不断增加新的功能并改进性能,XML数据存取APIs也在不断发展。因为未来的SQL Server版本将增加对XML的本地支持,而且APIs通过利用这些功能得以不断增强,所以API不断发展的这个趋势也将持续下去。然而,如今现有的APIs已经提供了强大的功能和性能组合,可以使你构建高性能的XML应用程序。

    关于作者:
    Greg Ewing是Clarity Consulting Inc.的顾问。除了为VSM、MSDN和内部刊物撰写文章外,Greg还负责几种技术的内部培训,包括C#、高级VB.NET、C++和COM。他的联系方式是gewing@claritycon.com

    Jon Rauschenberger是Clarity Consulting Inc.的合作伙伴和技术主管,这是一家位于芝加哥的信息技术咨询公司和Microsoft Gold Certified Partner。除了构建可扩展的基于 Web的解决方案外,Jon也在诸如Microsoft Tech-Ed、VBITS、COMDEX和DevDays这样的大会上做演讲。Jon也是芝加哥MSDN地区主管。联系方式jrausch@claritycon.com

  • 相关阅读:
    LeetCode 32. 最长有效括号(Longest Valid Parentheses)
    LeetCode 141. 环形链表(Linked List Cycle)
    LeetCode 160. 相交链表(Intersection of Two Linked Lists)
    LeetCode 112. 路径总和(Path Sum)
    LeetCode 124. 二叉树中的最大路径和(Binary Tree Maximum Path Sum)
    LightGBM新特性总结
    sql service 事务与锁
    C#泛型实例详解
    C# 中的委托和事件(详解)
    C# DateTime日期格式化
  • 原文地址:https://www.cnblogs.com/ghx88/p/425770.html
Copyright © 2011-2022 走看看