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

首頁 > 編程 > .NET > 正文

ADO.NET深入研究(2)[特別推薦]

2024-07-10 13:03:37
字體:
來源:轉載
供稿:網(wǎng)友
導 讀:.net 在數(shù)據(jù)存取方面做了很大的調(diào)整。在.net 框架下,數(shù)據(jù)存取是由ado.net來完成的,這是一個ado的改進和完善版本。它最顯著的變化是其完全基于xml。而對于從事ado開發(fā)的人員來說,recordset對象的消失也令他們感到驚奇。
--------------------------------------------------------------------------------

翻譯整理:.net技術網(wǎng)(www.51dotnet.com)slash
原文出處:http://www.dnjonline.com/articles/essentials/iss22_essentials.html

表4顯示了dataset 中現(xiàn)有的數(shù)據(jù)。可以發(fā)現(xiàn)現(xiàn)在有兩種數(shù)據(jù)類型,同時schema 也做了相應的調(diào)整來描述這兩種數(shù)據(jù)類型。

請注意我們現(xiàn)在并沒有做創(chuàng)建一個內(nèi)連接或外連接,而是類似于用shape 語言用兩個單獨的表創(chuàng)建了一個分級的recordset對象。當然你也可以創(chuàng)建連接,這在dataset中表現(xiàn)為一個表。

ado開發(fā)者在操作recordset 對象的時候,需要知道他們到底需要一個客戶端還是服務器端的光標。movefirst 或是 absoluteposition之類的操作,在服務器端光標的情況下將消耗很大的服務器資源,但在客戶端光標的情況下,確是高效和有力的工具。兩類光標存在著巨大的差異。一個客戶端光標的recordset 對象事實上更類似于一個高性能的數(shù)組,而不是一一種序列化的存取結構。

與之相對,dataset 始終是'客戶端的',并且可以發(fā)揮'高性能數(shù)組'存取模型的最高效率。在recordset 中有字段集合,但對于一個recordset 對象,卻沒有相應的集合。而dataset中的所有表都有一個列和一個行的集合,你可以使用簡單的隨機存取技術來操作它們,表5顯示了在ado.net 中操作dataset的對象模型。

通過循環(huán)的方式你可以對datatable中的每一行進行操作,然而我在下一個例子中采用了另一種方法:datatable 的 select 方法。這是一個重載方法,從本質(zhì)上來說,它相當于結合了recordset的filter 和 sort 屬性。select 方法返回一個以datarow對象為元素的數(shù)組--能夠利用標準的數(shù)組的方法對它處理。需要注意的是所有這些過程是在你程序的緩存中進行的,dataset 已經(jīng)和數(shù)據(jù)源完全的斷開了。

下面的示例代碼向dataset中填充兩個數(shù)據(jù)表(第二個表沒有使用 where 子句)然后用select 方法從'authors'返回一個數(shù)組,并利用該結果創(chuàng)建一個動態(tài)的下拉列表。

dim dc as new adodatasetcommand( _
"select au_id, au_fname," & _
" au_lname from authors", strconnect)
dim ds as new dataset()

' declare an array of datarows
dim dr() as datarow
dim i as integer

dc.filldataset(ds, "authors")
dc = new adodatasetcommand( _
"select * from titleauthor", strconnect)
dc.filldataset(ds, "titles")

dr = ds.tables("authors").select( _
"au_lname >= 'r'", "au_lname asc")

for i = 0 to ubound(dr)
listbox1.items.add( _
cstr(dr(i)("au_fname")) & " " _
& cstr(dr(i)("au_lname")))
next

在這里,select 語句返回所有的行,其中的 last name 的打頭字母在 'r'之前,并且對這些行進行了分類,'titles'表在這里被忽略了

表之間的聯(lián)系

如果你沒有利用shape language 進行過工作,你很可能只是創(chuàng)建一個擁有一個數(shù)據(jù)表的 dataset 并對其進行操作,就象recordset 對象一樣。當你一旦向dataset 中加入了多個表,你會希望在它們之間建立關聯(lián)以便于操作。在下面的代碼中,假定以與上例完全相同的方法創(chuàng)建了一個名為ds的dataset 對象:

dim dr() as datarow
dim drchildren() as datarow
dim dl as datarelation
dim i, j as integer

dl = new datarelation("authortitles", _
ds.tables("authors").columns("au_id"), _
ds.tables("titles").columns("au_id"))
ds.relations.add(dl)

dr = ds.tables("authors").select( _
"au_lname >= 'r'", "au_lname asc")

for i = 0 to ubound(dr)
listbox1.items.add( _
cstr(dr(i)("au_fname")) & " " _
& cstr(dr(i)("au_lname")))
drchildren = dr(i).getchildrows(dl)
for j = 0 to ubound(drchildren)
listbox1.items.add(" " & _
cstr(drchildren(j)("title_id")))
next
next

datasetcommands


表 6:
使用list box顯示兩個表的一多關系

這段代碼在'authors' 表和 'titles'表之間建立了一個父子關系的關聯(lián),這是通過創(chuàng)建一個datarelation對象(命名為dl)并將它加入dataset實現(xiàn)的。關聯(lián)指定 au_id 為關鍵字段,通過對子表('titles')中 au_id 的匹配來得到父表中每一行的子行。在ado 數(shù)據(jù)篩選的shape 語言中是,這是通過 relate 語句來實現(xiàn)的。

當你指定了父表中的行時,你可以利用這種關聯(lián)。你可以通過getchildrows方法得到所有子表中所有相關的行,當然這里的關聯(lián)關系是由你來決定的。datarelations 使得創(chuàng)建一個master-detail程序變的非常簡單。上面的代碼的顯示結果見表6。

下面我們來了解一下adodatasetcommand對象以及與它功能相似的sqldatasetcommand對象。我們已經(jīng)了解了它們?nèi)齻€主要功能中的一個,就是通過使用命令字符串和一個連接號向dataset 對象中加入數(shù)據(jù)。下面對另外兩個主要功能進行討論,首先是更新(updating)。

在傳統(tǒng)的ado中,一個客戶端的 recordset 對象通過sql 語句來進行更新。在這里sql 模擬開放式鎖定,因此更新得以被返回到數(shù)據(jù)庫。這是一個靈活的機制,但有兩個缺點:一、自動生成的sql語句不易更改,因此假如你寫一些高效率的存儲過程,將會比直接使用sql 語句迅速的多。二、這是第一個問題的延續(xù)。當需要更新的數(shù)據(jù)源無法理解ansi-sql的時候,你就無法使用客戶端的recordset了。象active directory, exchange 2000以及 indexing services這些兼容ado 的數(shù)據(jù)源,它們不兼容ansi 的標準。因此你如果想通過ado對它們進行更新,你就只能使用服務器端的光標了。

在ado.net 中這些問題被解決了。第一種方法,dataset 與數(shù)據(jù)源完全斷開,adodatasetcommand作為一個獨立的實體與數(shù)據(jù)源進行交互。更新完全由adodatasetcommand進行,而dataset則被完全隔離。

第二中方法,adodatasetcommand將更新的sql語句作為一種公開的屬性,這樣你可以輕松的替換sql 語句,或者是存儲過程。更為出色的是,如果你想使用存儲過程,visual studio.net 將為你生成,在下一部分我們可以看到具體的應用。

最后是關于數(shù)據(jù)表映射功能。數(shù)據(jù)的使用者不需要得到這樣一個數(shù)據(jù)表:列以'au_fname' 和 'au_lname'命名。不僅是不美觀的問題,更重要的是這樣會把數(shù)據(jù)庫的結構暴露出來了,數(shù)據(jù)映射允許你在dataset 中替換列的名字,如果需要,可以為不同的用戶提供不同的數(shù)據(jù)表映射,下面我將介紹如何利用visual studio.net ,在圖形化的界面下創(chuàng)建數(shù)據(jù)更新的代碼。

簡單的可視化設計

visual studio.net 為 windows forms, web forms, web services, components and xml schemas的設計提供了圖形化的設計工具。設計者只需要從工具條上的控件拖動到工作區(qū)域 就可以了。在這里,工作區(qū)域將與最終用戶看到的界面有很大區(qū)別。

當你將一個非可視的對象如adodatasetcommand拖動進來時,它將被顯示在設計視圖中,但用戶將無法看到這個對象。其他的數(shù)據(jù)控件也是這樣。

表7顯示了一個vb.net的項目,這個項目有一個窗體,上面有一個datagrid控件、一個commandbutton以及adodatasetcommand控件,在這里你可以象在visual studio 6中一樣來處理adodatasetcommand:在可視化的界面中你可以利用向導來建立adodatasetcommand的連接字符串,命令字符串;在與數(shù)據(jù)庫的接口上,你可以選擇自動生成sql語句,選擇已有的存儲過程,或是創(chuàng)建一個新的存儲過程。

表8顯示了向導的最終結果,你可以給你創(chuàng)建的存儲過程命名,或者只是預覽一下,然后將之存為文件以便以后修改。

如果你不想利用存儲過程,你也可以直接使用sql語句,你還可以在屬性面板上修改這些語句。你還可以做的工作包括給對列進行簡單化的命名,以便你今后能夠方便的使用。具體的操作可以參看表9的對話框。

在完成了以上的工作后,應用程序的編寫變的相對很輕松了,下面是datagrid的綁定的代碼:

me.adodatasetcommand1.filldataset(dsauthors)
me.datagrid1.datasource = dsauthors

adodatasetcommand1成為窗體me的一個屬性,它將dsauthors表裝入一個dataset 對象,接著設置datagrid的datasource屬性為dsauthors。最后是編寫commandbutton的click 事件:

me.adodatasetcommand1.update(dsauthors)

update 事件將根據(jù)對dsauthors的修改對數(shù)據(jù)源進行更新(具體的update 方法在存儲過程中已經(jīng)被設定)。這與ado 中斷開連接的recordsets對象的批量更新很相似,但效率更高。可以在表10中看到最終完成的應用程序,它的列名已經(jīng)被替換為新的列名。


表10: 運行結果

類型化的dataset

對于許多開發(fā)者來說,他們已經(jīng)習慣了使用ado 的 recordset 對象的,象使用字段(fields)而不是使用屬性(properties),這樣做有它的優(yōu)勢,但也有很多缺陷。首先,與屬性不同,字段并不是強類型的,它不為intellisense技術(自動提醒語法、參數(shù)和對象屬性)所支持。另外,因為不是強類型,所以你無法為它添加自定義的方法或是屬性,這意味著當你需要把一個recordset 對象的功能完全封裝起來的時候,你會遇到許多限制。

與之相對,因為.net 平臺支持繼承,所以你可以創(chuàng)建dataset 對象的子類,并向其中添加新的功能。這就是具有類型的 dataset,它基本上沒有什么使用范圍的限制,所有dataset 在.net 中內(nèi)建的特性都將被支持,包括綁定,和xml dom 的內(nèi)部操作。為了創(chuàng)建這樣一個具有類型的 dataset 對象,你所需要的只是一個xsd 格式的 xml schema。

當你基于一個datasetcommand 上創(chuàng)建具有類型的 dataset 的時候,你甚至可以讓visual studio.net 來創(chuàng)建這樣一個 xml schema,所有的工作只是鼠標在'generate dataset'菜單上的輕輕一點(見表7)。在這里使用的xml schema與表2中的是一樣的(除非你對數(shù)據(jù)表的結構做了改動)

在后面的例子中我將使用我創(chuàng)建的具有類型的authorsdataset 對象來代替dataset 對象。authorsdataset中的所有表和列都將是它的屬性,因此所寫出的代碼將更易于查看,而強類型將更不易出錯,同時還可以利用intellisense技術。表11顯示了類型化的dataset 的編程界面,注意intellisense菜單也被顯示出來了。



表11中我們可以看到在authorsdataset被創(chuàng)建之后,同時還創(chuàng)建了authorsselecttable(繼承于datatable),authorsselectrow(繼承于datarow),以及所有的列的類(繼承于datacolumn),由此,我們可以看到繼承對.net 的重要意義。

findbyauthor_id方法自動被添加到authorsselecttable類中,列屬性被自動添加到authorsselectrow類中,所有的類的代碼都是非隱藏的而且易于擴展。如果你已經(jīng)習慣了使用斷開連接的(disconnected)或是虛擬的(fabricated)recordset 對象,那么轉向ado.net 使用具有類型的 dataset 對象是一個很好的選擇。

ado 到 ado.net 是一個革命性的發(fā)展,在所有的.net framework領域中,許多基本的組件可以被重寫,因為不用受到二進制兼容性的強制性約束所以可以對所有類型的組件的接口進行重寫和改善,而ado.net 只是其中一例。

在經(jīng)過了幾個星期的使用后,我認為 ado.net 與ado 相比是一個更完善的模型,我非常滿意它對ado所做的改進。雖然某種程度上講,對于開發(fā)者來說,需要學習一種新的對象模型,但我仍建議開發(fā)者向.net轉移。ado.net 繼承了ado的優(yōu)良特性,并且更易于使用。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 宿迁市| 金阳县| 上蔡县| 汾西县| 大洼县| 周宁县| 青铜峡市| 蓬溪县| 佛教| 安泽县| 泽普县| 上饶市| 延庆县| 淳化县| 平塘县| 鸡泽县| 湄潭县| 平潭县| 石台县| 张家川| 文山县| 阳曲县| 剑阁县| 介休市| 铁岭市| 河西区| 庆阳市| 乌兰浩特市| 图木舒克市| 北票市| 江川县| 江北区| 准格尔旗| 板桥市| 和静县| 平遥县| 喀喇沁旗| 淮安市| 泰安市| 乐山市| 尉氏县|