国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

淺析.NET下XML數(shù)據(jù)訪問新機制

2024-07-10 13:01:14
字體:
供稿:網(wǎng)友
一.前言:

  xml作為web服務(wù)的基石,其重要性自然是不言而喻的,它正日益被開發(fā)人員所重視。同時隨著各類新興開發(fā)工具的推出,xml數(shù)據(jù)的訪問機制也變得越來越靈活多樣。.net框架為開發(fā)人員提供了幾種新的xml數(shù)據(jù)訪問機制,每種機制都提供了不同的xml數(shù)據(jù)訪問支持。所以對于開發(fā)人員而言,選擇正確合適的xml數(shù)據(jù)訪問機制變得相當重要,它會影響到項目開發(fā)的復(fù)雜度以及應(yīng)用程序的整體效率。

  大體來講,.net框架為開發(fā)人員提供了ado.net中的數(shù)據(jù)集xml數(shù)據(jù)訪問機制和sqldatareader xml數(shù)據(jù)訪問機制這兩種新的機制。為方便起見,我們不妨將前一種機制稱為ado.net機制,而后一種為sqldatareader機制。本文我就主要向大家介紹這兩種機制,同時我還會介紹sqlxml和ado 2.6這兩種比較傳統(tǒng)的xml數(shù)據(jù)訪問機制,并在最后將它們的性能做一個比較,以使讀者更清楚在具體的應(yīng)用中應(yīng)選擇哪種機制。本文的實例程序?qū)⒂玫絪ql server中的northwind數(shù)據(jù)庫,通過訪問該數(shù)據(jù)庫我們可以獲取相應(yīng)的xml數(shù)據(jù)并據(jù)此對不同的訪問機制進行性能比較和分析。

二.各種機制介紹:

  ado.net是ado升級版本,它為我們提供了全新的數(shù)據(jù)訪問機制,在提高數(shù)據(jù)訪問效率的同時它也大大簡化了開發(fā)人員的工作量,所以熟練掌握和運用ado.net進行開發(fā)是.net開發(fā)人員不可或缺的基本能力。

  ado.net為開發(fā)人員提供了兩種數(shù)據(jù)訪問模式:一種為連接模式(connected),另一種為非連接模式(disconnected)。前一種模式和傳統(tǒng)的ado模式是一樣的,而后一種模式則為.net所獨有也是為.net所推薦的,該模式的核心部分為ado.net中的數(shù)據(jù)集對象(dataset)。數(shù)據(jù)集對象的類位于system.data命名空間中,它對xml有相當完善的支持。在非連接模式下工作時,數(shù)據(jù)集對象能以xml的形式將數(shù)據(jù)存儲在主存中并提供用戶操作使用,因此通過一個簡單的方法它就能將關(guān)系型的數(shù)據(jù)轉(zhuǎn)化為層次化的具有良好模式的xml數(shù)據(jù),這就是前面提到的ado.net機制。

  下面,我就通過建立一個實例程序向大家介紹該機制下的xml數(shù)據(jù)訪問的具體方法。首先新建一個控制臺應(yīng)用程序的c#項目,該實例程序主要顯示了不同的xml數(shù)據(jù)訪問機制的運行效率。同時添加一個新的類,文件名不妨命名為dbxml.cs,該類包含了幾種xml數(shù)據(jù)訪問機制的不同實現(xiàn)方法,它們分別是: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


現(xiàn)在為該類添加executeadonetselect()方法,該方法執(zhí)行了對數(shù)據(jù)庫的select查詢操作,具體實現(xiàn)如下:

public string executeadonetselect(string customerid,
string connectionstring)
{
// 創(chuàng)建一個數(shù)據(jù)庫連接對象
sqlconnection myconnection = new sqlconnection(connectionstring);
// 創(chuàng)建一個數(shù)據(jù)適配器對象
sqldataadapter mysqldataadapter1 = new sqldataadapter("select *
from customers where customerid = @customerid", myconnection);
// 為其參數(shù)集添加參數(shù)
mysqldataadapter1.selectcommand.parameters.add("@customerid",
sqldbtype.char, 5, "customerid");
mysqldataadapter1.selectcommand.parameters["@customerid"].
value = customerid;
// 創(chuàng)建一個數(shù)據(jù)集對象
dataset mydataset = new dataset();
// 運用數(shù)據(jù)集對象的fill方法來填充數(shù)據(jù)集對象
mysqldataadapter1.fill(mydataset,"customers");
// 關(guān)閉數(shù)據(jù)庫連接
myconnection.close();
// 返回數(shù)據(jù)集對象中的數(shù)據(jù)的xml形式
return mydataset.getxml();
}



以上executeadonetselect()方法首先根據(jù)傳入的數(shù)據(jù)庫連接字符串創(chuàng)建一個sqlconnection對象,然后創(chuàng)建一個sqldataadapter對象,并傳遞一條select語句和上面的sqlconnection對象到其構(gòu)造函數(shù)中。其中的select語句中包含了一個用戶id參數(shù),所以你必須將該參數(shù)添加到sqldataadapter對象的selectcommand參數(shù)集中并為該參數(shù)賦值。接下來的兩步創(chuàng)建了一個新的dataset對象并用上面的sqldataadapter對象填充了該dataset對象,這兩步雖然簡單,但它們卻完成了大部分的工作。最后,關(guān)閉數(shù)據(jù)庫連接并以xml的形式返回數(shù)據(jù)集對象中的數(shù)據(jù)。

接下來為該類添加executesqldatareaderselect()方法,該方法如下:

public string executesqldatareaderselect(string customerid,
string connectionstring)
{
sqldatareader mydatareader = null;
// 創(chuàng)建一個數(shù)據(jù)庫連接對象
sqlconnection mysqlconnection = new sqlconnection
(connectionstring);
// 創(chuàng)建一個數(shù)據(jù)庫命令對象,并在sql語句中運用for xml子句
sqlcommand mysqlcommand = new sqlcommand("select * from customers
where customerid = @customerid for xml raw", mysqlconnection);
mysqlcommand.commandtype = commandtype.text;
// 為其參數(shù)集添加參數(shù)
mysqlcommand.parameters.add("@customerid", sqldbtype.char, 5,
"customerid");
mysqlcommand.parameters["@customerid"].value = customerid;
mysqlconnection.open();
// 執(zhí)行數(shù)據(jù)庫命令對象的executereader操作以取得一個數(shù)據(jù)閱讀器對象
mydatareader = mysqlcommand.executereader(commandbehavior.
closeconnection);
// 創(chuàng)建一個stringbuilder對象以構(gòu)造xml字符串
stringbuilder xml = new stringbuilder(8192);
// 不斷從數(shù)據(jù)閱讀器中獲取xml數(shù)據(jù)并添加到stringbuilder對象中
while (mydatareader.read())
{
if (!mydatareader.isdbnull(0))
xml.append(mydatareader.getstring(0));
}
mydatareader.close();
mysqlconnection.close();
// 返回xml數(shù)據(jù)的字符串形式
return xml.tostring();
}



sqldatareader類為我們提供了一種只讀的、向前的數(shù)據(jù)訪問方式,該特性使得它成為訪問sql server數(shù)據(jù)庫速度最快的一種方法。然而sqldatareader類并不直接支持xml類型的數(shù)據(jù),你必須手動編寫代碼將數(shù)據(jù)轉(zhuǎn)換成xml數(shù)據(jù)或者通過運行for xml查詢子句來返回xml類型的數(shù)據(jù)。這里,我們將使用for xml raw子句來獲取xml數(shù)據(jù)。

上面的executesqldatareaderselect()方法首先聲明一個sqldatareader對象,然后通過函數(shù)的數(shù)據(jù)庫連接字符串參數(shù)創(chuàng)建一個sqlconnection對象,并根據(jù)帶有for xml raw子句的select語句和上面的sqlconnection對象創(chuàng)建一個sqlcommand對象。之后,該方法為sqlcommand的參數(shù)集添加參數(shù)并為用戶id參數(shù)賦值。打開sqlconnection連接后,該方法將sqlcommand對象的executereader()方法的返回值賦給sqldatareader對象,并通過一個stringbuilder對象讀取sqldatareader對象中的xml數(shù)據(jù)。最后,該方法關(guān)閉sqldatareader對象和sqlconnection對象并以字符串的形式返回xml數(shù)據(jù)。

最后,為該類添加executesqlxmlselect()方法,該方法如下:

public string executesqlxmlselect(string customerid, string
connectionstring, bool clientside)
{
// 創(chuàng)建一個sqlxmlcommand對象
sqlxmlcommand cmd = new sqlxmlcommand(connectionstring);
cmd.roottag = "customers";
cmd.clientsidexml = clientside;
cmd.commandtext = "select * from customers where customerid =
'" + customerid + "' for xml raw";
// 執(zhí)行sqlxmlcommand對象的executexmlreader操作以取得一個xmlreader對象
xmlreader xr = cmd.executexmlreader();
// 創(chuàng)建一個xmldocument對象
xmldocument xd = new xmldocument();
// 運用其load方法將獲取的xml數(shù)據(jù)載入到一個dom中并返回xml數(shù)據(jù)的字符串形式
xd.load(xr);
return xd.outerxml
}



  sqlxml托管類是sqlxml 3.0包的一部分,sqlxml 3.0包擴展了sql server 2000的xml功能。sqlxml托管類是原生的.net類,它提供了通過編程方法訪問xml數(shù)據(jù)的功能。上面的executesqlxmlselect()方法首先運用數(shù)據(jù)庫連接字符串創(chuàng)建一個sqlxmlcommand對象。同時,由for xml子句獲取的xml數(shù)據(jù)往往只是一個xml片段,并不是結(jié)構(gòu)良好(well-formed)的xml數(shù)據(jù),要使得xml成為結(jié)構(gòu)良好的,你必須設(shè)定sqlxmlcommand對象的roottag屬性。在本實例中,我們將該屬性設(shè)置為"customers"。

  以前版本的sqlxml包是在服務(wù)器端生成xml數(shù)據(jù),然后傳遞給客戶端的。這樣,因為服務(wù)器端返回的xml數(shù)據(jù)流遠遠大于原來的二進制格式數(shù)據(jù)流,所以就產(chǎn)生了一個可擴展性問題。而3.0版本的sqlxml包允許服務(wù)器將數(shù)據(jù)以二進制的格式傳遞給客戶端,然后在客戶端將數(shù)據(jù)進一步轉(zhuǎn)變?yōu)閤ml格式,這樣就解決了原來版本中存在的可擴展性問題了。在3.0版本的sqlxml包中實現(xiàn)這個特性的方法很簡單,只要將sqlxmlcommand對象的clientsidexml屬性設(shè)置為true即可。這樣,程序會繼續(xù)使用帶有for xml子句的select語句,但是托管類會在發(fā)送sql語句到sql server之前將for xml子句先剝離掉。數(shù)據(jù)庫就不會發(fā)現(xiàn)for xml子句,因此從服務(wù)器返回給客戶端的數(shù)據(jù)也就是二進制格式的了。客戶端獲取從服務(wù)器返回的數(shù)據(jù)后,托管類會進而將數(shù)據(jù)轉(zhuǎn)化為xml格式。

  上面的程序中,我們通過執(zhí)行sqlxmlcommand對象的executexmlreader()方法來獲取一個xmlreader對象,并用它來填充一個xmldocument對象,最后返回xmldocument對象的outerxml屬性給調(diào)用者。

  上面,我給大家介紹了ado.net機制、sqldatareader機制和sqlxml機制這三種不同的方法,下面是運用這三種不同方法所得到的一個結(jié)果示意圖,從圖中的結(jié)果讀者可以看出那種方法的效率最高。




圖2


  最后要介紹的是ado 2.6機制,該機制是在vb 6.0中實現(xiàn)的。我們先創(chuàng)建一個名為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



  和其他實例一樣,上面的程序創(chuàng)建并打開一個數(shù)據(jù)庫連接。然后創(chuàng)建一個command對象,并將它的activeconnection屬性設(shè)置為上面的connection對象,而程序中用到的select語句和前面實例中的是一樣的。接著,程序?qū)ommand對象的execute()方法的返回值傳遞給一個recordset對象。然后,程序創(chuàng)建一個ado stream對象,并將其type屬性設(shè)置為adtypetext同時打開它。一旦該流對象被打開,調(diào)用recordset對象的save()方法就能將數(shù)據(jù)以xml的格式保存。最后,程序通過stream對象的readtext()方法返回xml數(shù)據(jù)給調(diào)用者。

  結(jié)合以上介紹的四種不同的xml數(shù)據(jù)訪問機制,我用asp和asp.net頁面以調(diào)用組件的方式對其xml數(shù)據(jù)訪問的性能和可擴展性進行了測試,結(jié)果得出如下圖所示的性能分析結(jié)果,以供讀者參考。




圖3


三.總結(jié):

  本文我向大家介紹了.net框架下xml數(shù)據(jù)訪問的四種不同機制,隨著微軟不斷的添加新功能并提高性能,xml數(shù)據(jù)訪問會繼續(xù)不停的向前發(fā)展。同時,鑒于新版本的sql server數(shù)據(jù)庫服務(wù)器會添加不少對xml的原生支持,我們可以期盼不久的將來xml數(shù)據(jù)訪問將得到極大的發(fā)展。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 珲春市| 儋州市| 宁海县| 平遥县| 南和县| 彰化县| 体育| 惠水县| 二连浩特市| 华容县| 札达县| 哈巴河县| 利川市| 宁陕县| 英山县| 商河县| 娱乐| 泗洪县| 徐汇区| 犍为县| 九台市| 华容县| 海淀区| 安远县| 灵山县| 轮台县| 虹口区| 唐山市| 平度市| 泗洪县| 西和县| 炉霍县| 丰都县| 鹰潭市| 香格里拉县| 芜湖县| 昌乐县| 芜湖县| 斗六市| 珠海市| 武宁县|