浅析.NET下XML数据访问新机制

2023-10-24 15:08

本文主要是介绍浅析.NET下XML数据访问新机制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一.前言:

  XML作为Web服务的基石,其重要性自然是不言而喻的,它正日益被开发人员所重视。同时随着各类新兴开发工具的推出,XML数据的访问机制也变得越来越灵活多样。.Net框架为开发人员提供了几种新的XML数据访问机制,每种机制都提供了不同的XML数据访问支持。所以对于开发人员而言,选择正确合适的XML数据访问机制变得相当重要,它会影响到项目开发的复杂度以及应用程序的整体效率。

  大体来讲,.Net框架为开发人员提供了ADO.Net中的数据集XML数据访问机制和SqlDataReader XML数据访问机制这两种新的机制。为方便起见,我们不妨将前一种机制称为ADO.Net机制,而后一种为SqlDataReader机制。本文我就主要向大家介绍这两种机制,同时我还会介绍SQLXML和ADO 2.6这两种比较传统的XML数据访问机制,并在最后将它们的性能做一个比较,以使读者更清楚在具体的应用中应选择哪种机制。本文的实例程序将用到SQL Server中的Northwind数据库,通过访问该数据库我们可以获取相应的XML数据并据此对不同的访问机制进行性能比较和分析。

二.各种机制介绍:

  ADO.Net是ADO升级版本,它为我们提供了全新的数据访问机制,在提高数据访问效率的同时它也大大简化了开发人员的工作量,所以熟练掌握和运用ADO.Net进行开发是.Net开发人员不可或缺的基本能力。

  ADO.Net为开发人员提供了两种数据访问模式:一种为连接模式(Connected),另一种为非连接模式(Disconnected)。前一种模式和传统的ADO模式是一样的,而后一种模式则为.Net所独有也是为.Net所推荐的,该模式的核心部分为ADO.Net中的数据集对象(DataSet)。数据集对象的类位于System.Data命名空间中,它对XML有相当完善的支持。在非连接模式下工作时,数据集对象能以XML的形式将数据存储在主存中并提供用户操作使用,因此通过一个简单的方法它就能将关系型的数据转化为层次化的具有良好模式的XML数据,这就是前面提到的ADO.Net机制。

  下面,我就通过建立一个实例程序向大家介绍该机制下的XML数据访问的具体方法。首先新建一个控制台应用程序的C#项目,该实例程序主要显示了不同的XML数据访问机制的运行效率。同时添加一个新的类,文件名不妨命名为DBXml.cs,该类包含了几种XML数据访问机制的不同实现方法,它们分别是:ExecuteADONetSelect、ExecuteSqlDataReaderSelect以及ExecuteSqlXmlSelect,分别代表了ADO.Net机制、SqlDataReader机制和SQLXML机制,而ADO 2.6这种机制则会在后面介绍。接着,为该类添加必要的命名空间。

        using System;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.Xml;
using Microsoft.Data.SqlXml;


其中对于Microsoft.Data.SqlXml命名空间需要先添加对Microsoft.Data.SqlXml组件的引用,而该组件是在安装了SQLXML 3.0以后就会有的,添加的方法如图1所示:



图1


现在为该类添加ExecuteADONetSelect()方法,该方法执行了对数据库的SELECT查询操作,具体实现如下:

        public string ExecuteADONetSelect(string CustomerID, 
string ConnectionString)
{
// 创建一个数据库连接对象
SqlConnection myConnection = new SqlConnection(ConnectionString);
// 创建一个数据适配器对象
SqlDataAdapter mySqlDataAdapter1 = new SqlDataAdapter("SELECT *
FROM customers WHERE CustomerID = @CustomerID", myConnection);
// 为其参数集添加参数 
mySqlDataAdapter1.SelectCommand.Parameters.Add("@CustomerID",
SqlDbType.Char, 5, "CustomerID");
mySqlDataAdapter1.SelectCommand.Parameters["@CustomerID"].
Value = CustomerID;
// 创建一个数据集对象
DataSet myDataSet = new DataSet();
// 运用数据集对象的Fill方法来填充数据集对象
mySqlDataAdapter1.Fill(myDataSet,"Customers");
// 关闭数据库连接
myConnection.Close();
// 返回数据集对象中的数据的XML形式
return myDataSet.GetXml();
}


以上ExecuteADONetSelect()方法首先根据传入的数据库连接字符串创建一个SqlConnection对象,然后创建一个SqlDataAdapter对象,并传递一条SELECT语句和上面的SqlConnection对象到其构造函数中。其中的SELECT语句中包含了一个用户ID参数,所以你必须将该参数添加到SqlDataAdapter对象的SelectCommand参数集中并为该参数赋值。接下来的两步创建了一个新的DataSet对象并用上面的SqlDataAdapter对象填充了该DataSet对象,这两步虽然简单,但它们却完成了大部分的工作。最后,关闭数据库连接并以XML的形式返回数据集对象中的数据。

接下来为该类添加ExecuteSqlDataReaderSelect()方法,该方法如下:

        public string ExecuteSqlDataReaderSelect(string CustomerID, 
string ConnectionString)
{ 
SqlDataReader myDataReader = null;
// 创建一个数据库连接对象
SqlConnection mySqlConnection = new SqlConnection
(ConnectionString);
// 创建一个数据库命令对象,并在SQL语句中运用FOR XML子句
SqlCommand mySqlCommand = new SqlCommand("SELECT * FROM Customers 
WHERE CustomerID = @CustomerID FOR XML RAW", mySqlConnection);
mySqlCommand.CommandType = CommandType.Text;
// 为其参数集添加参数
mySqlCommand.Parameters.Add("@CustomerID", SqlDbType.Char, 5,
"CustomerID");
mySqlCommand.Parameters["@CustomerID"].Value = CustomerID;
mySqlConnection.Open();
// 执行数据库命令对象的ExecuteReader操作以取得一个数据阅读器对象
myDataReader = mySqlCommand.ExecuteReader(CommandBehavior.
CloseConnection);
// 创建一个StringBuilder对象以构造XML字符串
StringBuilder xml = new StringBuilder(8192);
// 不断从数据阅读器中获取XML数据并添加到StringBuilder对象中
while (myDataReader.Read())
{
if (!myDataReader.IsDBNull(0))
xml.Append(myDataReader.GetString(0));
}
myDataReader.Close();
mySqlConnection.Close();
// 返回XML数据的字符串形式
return xml.ToString();
}


SqlDataReader类为我们提供了一种只读的、向前的数据访问方式,该特性使得它成为访问SQL Server数据库速度最快的一种方法。然而SqlDataReader类并不直接支持XML类型的数据,你必须手动编写代码将数据转换成XML数据或者通过运行FOR XML查询子句来返回XML类型的数据。这里,我们将使用FOR XML RAW子句来获取XML数据。

上面的ExecuteSqlDataReaderSelect()方法首先声明一个SqlDataReader对象,然后通过函数的数据库连接字符串参数创建一个SqlConnection对象,并根据带有FOR XML RAW子句的SELECT语句和上面的SqlConnection对象创建一个SqlCommand对象。之后,该方法为SqlCommand的参数集添加参数并为用户ID参数赋值。打开SqlConnection连接后,该方法将SqlCommand对象的ExecuteReader()方法的返回值赋给SqlDataReader对象,并通过一个StringBuilder对象读取SqlDataReader对象中的XML数据。最后,该方法关闭SqlDataReader对象和SqlConnection对象并以字符串的形式返回XML数据。

最后,为该类添加ExecuteSqlXmlSelect()方法,该方法如下:

        public string ExecuteSqlXmlSelect(string CustomerID, string
ConnectionString, bool ClientSide)
{
// 创建一个SqlXmlCommand对象
SqlXmlCommand cmd = new SqlXmlCommand(ConnectionString);
cmd.RootTag = "Customers";
cmd.ClientSideXml = ClientSide;
cmd.CommandText = "SELECT * FROM Customers WHERE CustomerID =
'" + CustomerID + "' FOR XML RAW";
// 执行SqlXmlCommand对象的ExecuteXmlReader操作以取得一个XmlReader对象
XmlReader xr = cmd.ExecuteXmlReader();
// 创建一个XmlDocument对象
XmlDocument xd = new XmlDocument();
// 运用其Load方法将获取的XML数据载入到一个DOM中并返回XML数据的字符串形式
xd.Load(xr);
return xd.OuterXml
}


  SQLXML托管类是SQLXML 3.0包的一部分,SQLXML 3.0包扩展了SQL Server 2000的XML功能。SQLXML托管类是原生的.NET类,它提供了通过编程方法访问XML数据的功能。上面的ExecuteSqlXmlSelect()方法首先运用数据库连接字符串创建一个SqlXmlCommand对象。同时,由FOR XML子句获取的XML数据往往只是一个XML片段,并不是结构良好(Well-Formed)的XML数据,要使得XML成为结构良好的,你必须设定SqlXmlCommand对象的RootTag属性。在本实例中,我们将该属性设置为"Customers"。

  以前版本的SQLXML包是在服务器端生成XML数据,然后传递给客户端的。这样,因为服务器端返回的XML数据流远远大于原来的二进制格式数据流,所以就产生了一个可扩展性问题。而3.0版本的SQLXML包允许服务器将数据以二进制的格式传递给客户端,然后在客户端将数据进一步转变为XML格式,这样就解决了原来版本中存在的可扩展性问题了。在3.0版本的SQLXML包中实现这个特性的方法很简单,只要将SqlXmlCommand对象的ClientSideXml属性设置为True即可。这样,程序会继续使用带有FOR XML子句的SELECT语句,但是托管类会在发送SQL语句到SQL Server之前将FOR XML子句先剥离掉。数据库就不会发现FOR XML子句,因此从服务器返回给客户端的数据也就是二进制格式的了。客户端获取从服务器返回的数据后,托管类会进而将数据转化为XML格式。

  上面的程序中,我们通过执行SqlXmlCommand对象的ExecuteXmlReader()方法来获取一个XmlReader对象,并用它来填充一个XmlDocument对象,最后返回XmlDocument对象的OuterXml属性给调用者。

  上面,我给大家介绍了ADO.Net机制、SqlDataReader机制和SQLXML机制这三种不同的方法,下面是运用这三种不同方法所得到的一个结果示意图,从图中的结果读者可以看出那种方法的效率最高。



图2


  最后要介绍的是ADO 2.6机制,该机制是在VB 6.0中实现的。我们先创建一个名为DBXMLVS6的ActiveX DLL项目,然后把Class1修改为ADO26,接着添加一个到ActiveX Data Objects 2.6的引用。一旦完毕,为该类添加一个ExecuteSelect()方法如下:

        Public Function ExecuteSelect(
CustomerID As String,
ConnectionString As String) 
As String
Set conn = New ADODB.Connection
conn.ConnectionString = ConnectionString
conn.Open
Set cmd = New ADODB.Command
cmd.ActiveConnection = conn
cmd.CommandText = "select * from customers 
where CustomerID = '" & CustomerID & "'" 
Set rs = cmd.Execute
Set adoStream = New ADODB.Stream
adoStream.Type = adTypeText
adoStream.Open    
rs.Save adoStream, adPersistXML
'返回XML字符串
ExecuteSelect = adoStream.ReadText()
End Function


  和其他实例一样,上面的程序创建并打开一个数据库连接。然后创建一个Command对象,并将它的ActiveConnection属性设置为上面的Connection对象,而程序中用到的SELECT语句和前面实例中的是一样的。接着,程序将Command对象的Execute()方法的返回值传递给一个RecordSet对象。然后,程序创建一个ADO Stream对象,并将其Type属性设置为adTypeText同时打开它。一旦该流对象被打开,调用RecordSet对象的Save()方法就能将数据以XML的格式保存。最后,程序通过Stream对象的ReadText()方法返回XML数据给调用者。

  结合以上介绍的四种不同的XML数据访问机制,我用ASP和ASP.Net页面以调用组件的方式对其XML数据访问的性能和可扩展性进行了测试,结果得出如下图所示的性能分析结果,以供读者参考。



图3


三.总结:

  本文我向大家介绍了.Net框架下XML数据访问的四种不同机制,随着微软不断的添加新功能并提高性能,XML数据访问会继续不停的向前发展。同时,鉴于新版本的SQL Server数据库服务器会添加不少对XML的原生支持,我们可以期盼不久的将来XML数据访问将得到极大的发展。

这篇关于浅析.NET下XML数据访问新机制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/275989

相关文章

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,

Java利用JSONPath操作JSON数据的技术指南

《Java利用JSONPath操作JSON数据的技术指南》JSONPath是一种强大的工具,用于查询和操作JSON数据,类似于SQL的语法,它为处理复杂的JSON数据结构提供了简单且高效... 目录1、简述2、什么是 jsONPath?3、Java 示例3.1 基本查询3.2 过滤查询3.3 递归搜索3.4

MySQL大表数据的分区与分库分表的实现

《MySQL大表数据的分区与分库分表的实现》数据库的分区和分库分表是两种常用的技术方案,本文主要介绍了MySQL大表数据的分区与分库分表的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有... 目录1. mysql大表数据的分区1.1 什么是分区?1.2 分区的类型1.3 分区的优点1.4 分

Mysql删除几亿条数据表中的部分数据的方法实现

《Mysql删除几亿条数据表中的部分数据的方法实现》在MySQL中删除一个大表中的数据时,需要特别注意操作的性能和对系统的影响,本文主要介绍了Mysql删除几亿条数据表中的部分数据的方法实现,具有一定... 目录1、需求2、方案1. 使用 DELETE 语句分批删除2. 使用 INPLACE ALTER T

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

Redis 中的热点键和数据倾斜示例详解

《Redis中的热点键和数据倾斜示例详解》热点键是指在Redis中被频繁访问的特定键,这些键由于其高访问频率,可能导致Redis服务器的性能问题,尤其是在高并发场景下,本文给大家介绍Redis中的热... 目录Redis 中的热点键和数据倾斜热点键(Hot Key)定义特点应对策略示例数据倾斜(Data S

Python实现将MySQL中所有表的数据都导出为CSV文件并压缩

《Python实现将MySQL中所有表的数据都导出为CSV文件并压缩》这篇文章主要为大家详细介绍了如何使用Python将MySQL数据库中所有表的数据都导出为CSV文件到一个目录,并压缩为zip文件到... python将mysql数据库中所有表的数据都导出为CSV文件到一个目录,并压缩为zip文件到另一个

SpringBoot整合jasypt实现重要数据加密

《SpringBoot整合jasypt实现重要数据加密》Jasypt是一个专注于简化Java加密操作的开源工具,:本文主要介绍详细介绍了如何使用jasypt实现重要数据加密,感兴趣的小伙伴可... 目录jasypt简介 jasypt的优点SpringBoot使用jasypt创建mapper接口配置文件加密

使用Python高效获取网络数据的操作指南

《使用Python高效获取网络数据的操作指南》网络爬虫是一种自动化程序,用于访问和提取网站上的数据,Python是进行网络爬虫开发的理想语言,拥有丰富的库和工具,使得编写和维护爬虫变得简单高效,本文将... 目录网络爬虫的基本概念常用库介绍安装库Requests和BeautifulSoup爬虫开发发送请求解

Oracle存储过程里操作BLOB的字节数据的办法

《Oracle存储过程里操作BLOB的字节数据的办法》该篇文章介绍了如何在Oracle存储过程中操作BLOB的字节数据,作者研究了如何获取BLOB的字节长度、如何使用DBMS_LOB包进行BLOB操作... 目录一、缘由二、办法2.1 基本操作2.2 DBMS_LOB包2.3 字节级操作与RAW数据类型2.