国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
掌握ADO.NET的十個(gè)熱門技巧
ADO.NET提供了一個(gè)統(tǒng)一的編程模式和一組公用的類來進(jìn)行任何類型的數(shù)據(jù)訪問,而不管你用何種語言來開發(fā)代碼。ADO.NET是全新的,但又與ADO盡可能保持一致,它使編程模式從一個(gè)客戶端/服務(wù)器、基于連接的模式轉(zhuǎn)變到了一個(gè)新的模式,這個(gè)新模式可以讓斷開的前端下載記錄、離線工作、然后重新連接來提交變化。ADO.NET是WinForms應(yīng)用程序、ASP.NET應(yīng)用程序和Web services的一個(gè)共有的特點(diǎn)。其功能可以跨LAN和Internet連接來實(shí)現(xiàn),可以在有狀態(tài)(stateful)和無狀態(tài)(stateless)情況下實(shí)現(xiàn)。

這就意味著,作為一個(gè)共有的技術(shù),ADO.NET的對象在所有可能的環(huán)境中并不是同等強(qiáng)大的。用ADO.NET為一個(gè)富客戶端(rich client)構(gòu)建一個(gè)數(shù)據(jù)層同為一個(gè)客戶端通常是共享的和重要的實(shí)體(如Web服務(wù)器)的Web應(yīng)用程序構(gòu)建一個(gè)數(shù)據(jù)層并不一樣。

如果你從前是個(gè)ADO開發(fā)人員,現(xiàn)在已經(jīng)用ADO.NET了,那么你可能把數(shù)據(jù)訪問看做是一個(gè)萬能的對象,如Recordset。我們很自然地會將舊的對象模式同新的對象模式匹配起來,并將現(xiàn)有的方法用于.NET應(yīng)用程序。然而,在ADO環(huán)境中的某些好的方法在轉(zhuǎn)換到ADO.NET環(huán)境時(shí)就可能并不強(qiáng)大了。而且,看起來很微不足道的ADO.NET對象模式的復(fù)雜性可能會導(dǎo)致很糟糕的編程情況、不理想的代碼、甚至是功能不能實(shí)現(xiàn)。我將講述在ADO.NET編程中可能會給你帶來麻煩的10個(gè)方面,并提供技巧和解決方法來避免它們。

1. 避免Database-Agnostic形式的編程
ADO.NET中的數(shù)據(jù)訪問是強(qiáng)類型的,就是說在任何時(shí)候你都必須了解你正在處理的是什么數(shù)據(jù)源(data source)。相反,在ADO中,你可以編寫數(shù)據(jù)訪問代碼(它們充分利用了OLE DB提供者的通用模式),并將基本的數(shù)據(jù)源只看做是個(gè)參數(shù)。ADO對象模式提供了唯一的連接和命令對象,它們隱藏了基本的DBMS的特征。一旦你在Connection對象上設(shè)置了Provider屬性,那么為SQL Server或Oracle創(chuàng)建一個(gè)命令對象就需要同樣的代碼。許多開發(fā)人員都通過該功能來使用生產(chǎn)環(huán)境外的Access數(shù)據(jù)庫,以便很快地測試或演示應(yīng)用程序。

在ADO.NET中是不能這么做的,因?yàn)樵贏DO.NET中,至少連接對象必須是特定于數(shù)據(jù)源的。你不能以一種間接或通用的方式來創(chuàng)建連接,除非你決定運(yùn)用ADO的數(shù)據(jù)訪問技術(shù)——OLE DB。在ADO.NET中,你可以用OleDbConnection類創(chuàng)建到一個(gè)數(shù)據(jù)庫的連接,這個(gè)類可以讓你訪問各種數(shù)據(jù)源。在.NET托管環(huán)境中運(yùn)用System.Data.OleDb名字空間中的類并不特別有效,因?yàn)樗鼈兪怯肙LE DB來訪問數(shù)據(jù)的。你只能用OLE DB來訪問那些沒有.NET數(shù)據(jù)提供者的數(shù)據(jù)源。

如果你的應(yīng)用程序必須訪問全異的數(shù)據(jù)源(而且你知道可能涉及什么數(shù)據(jù)源——一個(gè)合理的假設(shè)),那么你可以創(chuàng)建一個(gè)集中的factory類,它返回一個(gè)連接對象,并通過一個(gè)通用的接口(IDbConnection接口)來管理這個(gè)連接對象。Factory類在內(nèi)部運(yùn)用應(yīng)用程序參數(shù)來決定使用什么.NET數(shù)據(jù)提供者:' Create the connection
Dim factory As New MyAppConnectionFactory
Dim conn As IDbConnection
conn = factory.CreateConnection(connString)

' Create the command
Dim cmd As IDbCommand = conn.CreateCommand(query)




一旦你得到了一個(gè)連接對象,你就可以以database-agnostic的方式來創(chuàng)建和執(zhí)行一個(gè)命令了,而不管使用的數(shù)據(jù)源是什么。你可以使用CreateCommand方法并通過IDbCommand接口來引用命令。然后,你可以用IDbCommand接口上的ExecuteReader方法或ExecuteNonQuery方法來執(zhí)行命令。如果你用ExecuteReader,你就可以得到一個(gè)data reader并可以用IDataReader接口來對它進(jìn)行一般的訪問了。

你不能用一個(gè)通用的數(shù)據(jù)庫編程模式來填充一個(gè)DataSet對象。實(shí)際上,你不能像創(chuàng)建一個(gè)命令那樣以一種間接的方式來創(chuàng)建data adapter對象。原因就是,在有些情況下,data adapter不同于命令對象,它可以在內(nèi)部隱含地創(chuàng)建一個(gè)連接。然而,它必須以一種強(qiáng)類型的方式工作,而且必須知道基本的數(shù)據(jù)庫服務(wù)器是什么。

2. 運(yùn)用字符串來串行化擴(kuò)展的屬性
幾個(gè)ADO.NET對象都擁有一個(gè)叫做ExtendedProperties的集合。該屬性就像收集貨物(cargo collection)一樣,可以用來存儲任何類型的用戶信息。DataSet、DataTable和DataColumn就是可以提供該數(shù)據(jù)成員的類。ADO.NET通過運(yùn)用PropertyCollection類封裝的一個(gè)哈希表來實(shí)現(xiàn)這個(gè)ExtendedProperties屬性。你可以用Add方法將數(shù)據(jù)插入到集合中。Add方法使用了兩個(gè)參數(shù)來保存數(shù)據(jù)——key和value。該方法的原形將參數(shù)定義為通用的對象類型,你可以存儲任何類型的信息。然而,在特殊情況下,你應(yīng)該特別注意那些被保存為擴(kuò)展屬性的對象的類型。

如果你想將包含擴(kuò)展屬性的ADO.NET對象串行化到XML,最好只用字符串。如果不行,你必須對ADO.NET的內(nèi)在的serializer的行為采取對策。

當(dāng)ADO.NET將一個(gè)DataSet對象保存到XML時(shí),ExtendedProperties集合的內(nèi)容就被串行化到內(nèi)存中了,但大概是出于性能的原因,ADO.NET運(yùn)用了ToString方法,而不是XML serializer來實(shí)現(xiàn)串行化。更重要的是,當(dāng)ADO.NET對象被讀回并復(fù)原時(shí),ExtendedProperties集合包含的是對象的字符串表現(xiàn)形式,而不是對象本身。

3. 運(yùn)用具有BLOB字段的ExecuteXmlReader
用于SQL Server的.NET數(shù)據(jù)提供者(data provider)使用了數(shù)據(jù)庫提供的XML擴(kuò)展名,并提供了一個(gè)額外的方法(ExecuteXmlReader)來執(zhí)行查詢。命令對象上的所有的執(zhí)行者(例如ExecuteReader和ExecuteScaler)都采用不同的方法來得到結(jié)果集。ExcecuteReader通過一個(gè)托管指針(managed cursor)(data reader)來返回?cái)?shù)據(jù),而ExecuteScaler返回結(jié)果集中的第一個(gè)值,把它作為一個(gè)標(biāo)量值。ExecuteXmlReader執(zhí)行查詢,并返回已經(jīng)綁定到一個(gè)XmlTextReader對象的基于XML的輸出流。通過這種方式,你就不需要做額外的工作來以XML的方式加工數(shù)據(jù)了。要實(shí)現(xiàn)這一點(diǎn),查詢字符串必須返回XML數(shù)據(jù)。對SQL Server來說,當(dāng)查詢字符串包含一個(gè)FOR XML子句時(shí),就可以實(shí)現(xiàn)它。盡管這只是一種可能。

一個(gè)不太為人所知的情況是,要使ExecuteXmlReader工作,讓結(jié)果集包含XML數(shù)據(jù)就足夠了。 下面的查詢方法很好,只要列包含XML格式的文本就行:SELECT data FROM table WHERE key=1

這個(gè)列是個(gè)典型的BLOB或ntext字段,其文本顯示為XML。簡要地看看ExecuteXmlReader方法的內(nèi)部結(jié)構(gòu)會有助于我們的理解。該方法用ExecuteReader來執(zhí)行查詢,并從數(shù)據(jù)提供者得到一個(gè)數(shù)據(jù)流對象。接下來,它將數(shù)據(jù)流綁定到XmlTextReader類的一個(gè)新創(chuàng)建的實(shí)例上,這個(gè)實(shí)例被返回給調(diào)用者。連接一直處于忙碌狀態(tài),直到XML reader停止工作。SQL Server提供者是唯一的提供者,它提供了方法讓我們從一個(gè)XML reader直接讀取數(shù)據(jù),但這種做法更多的是與提供者有關(guān),而與數(shù)據(jù)庫性能的關(guān)系并不大。Oracle支持XML查詢,但Oracle的數(shù)據(jù)提供者并不支持XML查詢。相比之下,為OLE DB數(shù)據(jù)提供者編寫一個(gè)ExecuteXmlReader方法并不難(點(diǎn)此下載實(shí)例)。

4. 不要設(shè)法緩存一個(gè)DataView
DataSet和DataTable對象是唯一的包含數(shù)據(jù)的ADO.NET對象。DataView是一個(gè)不能串行化的、輕量級的類,它只代表構(gòu)建在一個(gè)表上的視圖(view)。你可以根據(jù)一個(gè)表達(dá)式或行的狀態(tài)來過濾視圖。許多應(yīng)用程序都需要你管理數(shù)據(jù)視圖并將它們綁定到數(shù)據(jù)控件上,如Windows和Web DataGrid控件。一個(gè)DataView對象不能緩存數(shù)據(jù);它只是緩存了與當(dāng)前過濾器相匹配的基本的表中的行的索引。緩存索引的順序與當(dāng)前的排序表達(dá)式一致。緩存DataView而不緩存基本的DataTable是不行的。

例如,提供分頁(比如通過運(yùn)用DataGrid控件)的ASP.NET應(yīng)用程序通常以一個(gè)DataView對象結(jié)尾,因?yàn)樗С峙判蚝瓦^濾。在有些情況下(大多是基于性能的原因),你可能決定要緩存數(shù)據(jù)源。要緩存的對象不能是DataView(它是你實(shí)際綁定的對象)。一個(gè)DataView只是一種索引,如果沒有基本的DataTable對象,它是沒有用的。

5. 運(yùn)用Find來讀取一個(gè)記錄
通過運(yùn)用DataTable的Select方法來運(yùn)行一個(gè)內(nèi)存中的查詢,或在視圖上設(shè)置一個(gè)過濾器來濾掉與指定標(biāo)準(zhǔn)不匹配的所有的記錄,你就可以讀取一個(gè)DataTable對象中的一個(gè)特定的行了。你可以通過設(shè)置DataView類上的RowFilter屬性來設(shè)置一個(gè)過濾器。這兩種方法都運(yùn)用相同的引擎來選擇記錄。它們可以接納一個(gè)表達(dá)式,對它進(jìn)行解析并求各個(gè)子句的值。DataTable的Select方法返回一個(gè)帶有所有相匹配的DataRow對象的數(shù)組。RowFilter屬性重建DataView的內(nèi)部索引來包含所有的(且僅包含)匹配的記錄。然后,應(yīng)用程序就可以訪問記錄了。這兩種方法在性能上幾乎是一樣的;運(yùn)用哪種方法取決于環(huán)境和個(gè)人喜好。例如,如果你用的是數(shù)據(jù)綁定的控件,如一個(gè)DataGrid或DataList,那么RowFilter就很理想。如果你必須處理一串記錄,那么Select方法就更好了。

然而,你還可以用另一種方法(仍然是基于DataView的),它是讀取一個(gè)表中的記錄的最快的方法。該方法就是用Find:Dim view As DataView 
view = New DataView(table)
view.Sort = "orderid"
Dim index As Integer = view.Find(10248)
Dim row As DataRow = view(index).Row




Find方法運(yùn)用了視圖的當(dāng)前索引,并將指定的值(或多個(gè)值)與形成當(dāng)前索引的字段匹配起來。在前面的代碼中,值10248與列orderid匹配。如果Sort屬性為空,且DataTable對象有一個(gè)主鍵,那么就運(yùn)用主鍵中的列。Find方法返回的是相匹配的第一行的基于0的位置的值。

如果你想返回多個(gè)記錄,可以用FindRows的演變形式: view.Sort = "orderid, discount"
Dim keys(1) As Object
keys(0) = 10248
keys(1) = 0
Dim row As DataRow = _
view(view.Find(keys)).Row




前面的代碼可以讓你通過運(yùn)用Find的重載方法(帶有一組對象)來匹配多個(gè)列的值。

6. 盡可能用預(yù)先排序的數(shù)據(jù)
ADO.NET對象模式使我們可以很容易地實(shí)現(xiàn)排序。你可以創(chuàng)建一個(gè)DataView對象并設(shè)置其Sort屬性;ADO.NET runtime查看新的排序表達(dá)式并為視圖重編索引。該步驟是在內(nèi)存中實(shí)現(xiàn)的,但速度并不快。排序的花費(fèi)很高,更重要的是,它并不是個(gè)線性操作(linear operation)。對一組數(shù)據(jù)進(jìn)行排序需要n*log(n)的計(jì)算成本,就是說,隨著需要排序的條目數(shù)量的增加,直線增加的成本是很大的。因此,你應(yīng)該限制應(yīng)用程序中的排序,盡可能地運(yùn)用預(yù)先排序的數(shù)據(jù)。在Web應(yīng)用程序中,動態(tài)排序?qū)π阅艿挠绊懯窍喈?dāng)大的。既然如此,你就應(yīng)該設(shè)計(jì)應(yīng)用程序,限制對動態(tài)排序的需求,并依賴在數(shù)據(jù)庫服務(wù)器中寫死的算法。除非你在用應(yīng)用程序的一個(gè)可以使復(fù)雜性低于n*log(n)極限的特殊的功能,否則避免運(yùn)用手工排序算法,因?yàn)檫@種算法可能比系統(tǒng)中的算法更糟。

7. ADOX可以幫你得到并改變Schema信息
ADO.NET并沒有為得到并管理schema信息提供一個(gè)完全的對象模式。你應(yīng)該用ActiveX Data Objects Extensions for Data Definition Language and Security (ADOX)或用每個(gè)數(shù)據(jù)庫提供的本地功能來得到并改變Schema信息。ADOX是ADO對象的一個(gè)擴(kuò)展,它包括用來創(chuàng)建和修改Schema的對象。你可以編寫適用于各種數(shù)據(jù)源的代碼(不管本地語法有什么不同),因?yàn)锳DOX是管理schema的一個(gè)基于對象的方法。

你可以用一個(gè)data reader對象來讀(不是設(shè)置)簡單的schema信息。所有的data reader類(OleDbDataReader、SqlDataReader、OracleDataReader)都提供了一個(gè)GetSchemaTable方法,該方法可以讀取查詢到的列的元數(shù)據(jù)信息。GetSchemaTable返回一個(gè)DataTable對象(格式是每列一行)和固定的一組包含信息的列。返回的元數(shù)據(jù)可以分成三類:列元數(shù)據(jù)、數(shù)據(jù)庫特征和列屬性。返回的列可以是AllowDBNull、IsAutoIncrement、ColumnName、IsExpression、IsReadonly和NumericPrecision等。在MSDN資料中有完整的列表(見附加資源)。

在調(diào)用ExecuteReader時(shí),如果你執(zhí)行KeyInfo命令,那么GetSchemaTable方法就可以返回更精確的數(shù)據(jù)。你可以將KeyInfo行為同缺省的行為結(jié)合起來,執(zhí)行一個(gè)單獨(dú)的命令并得到schema和數(shù)據(jù):reader = cmd.ExecuteReader( _
CommandBehavior.KeyInfo Or _ 
CommandBehavior.CloseConnection)



只有執(zhí)行KeyInfo,IsKey、BaseTableName、IsAliased、IsExpression和IsHidden字段的值才能被正確返回。如果執(zhí)行KeyInfo,關(guān)鍵的列(如果有)通常是添加在結(jié)果集的底部的,但不給它們返回?cái)?shù)據(jù)。

8. 用一個(gè)派生的類和自定義的串行化來節(jié)省空間
只有兩個(gè)ADO.NET對象是被標(biāo)記為可串行化的——DataTable和DataSet。.NET Framework中的串行化是通過formatter對象來完成的,它們可以將一個(gè)對象實(shí)例保存到一個(gè)二進(jìn)制或一個(gè)SOAP流(stream)中。.NET formatter用Reflection來提取任何必要的信息。然而,如果這個(gè)類實(shí)現(xiàn)了ISerializable接口,那么.NET formatter就會給接口的方法讓步,讓它們負(fù)責(zé)拷貝需要串行化到一個(gè)內(nèi)存緩沖器中的所有的信息。DataTable和DataSet類都通過ISerializable接口支持串行化。

如果你將一個(gè)DataTable或一個(gè)DataSet串行到一個(gè)二進(jìn)制(binary stream)中,你應(yīng)該可以得到非常緊湊的輸出結(jié)果。雖然你得到的結(jié)果文件是最小的,但遺憾的是,它實(shí)際上并不小。荒謬的是,你保存到一個(gè)二進(jìn)制的DataSet比你用WriteXml方法保存到XML的同樣的DataSet要大很多。

要解釋這種情況,我們需要來看看ADO.NET對象是用什么方式被串行起來的。在串行一個(gè)DataSet對象時(shí),它將基于XML的DiffGram表示法保存在formatter的緩沖器中。在串行一個(gè)DataTable時(shí),它首先創(chuàng)建了一個(gè)臨時(shí)的DataSet對象,將它定義為它的parent,然后作為一個(gè)DiffGram串行起來。

一個(gè)DiffGram是一個(gè)XML流,它提供了一個(gè)DataSet中表和行的有狀態(tài)的表示法。一個(gè)DiffGram文件是很詳細(xì)的,有些冗長。DiffGram包含當(dāng)前的數(shù)據(jù),以及被修改的行和未解決的錯(cuò)誤的初始值。當(dāng)我們保存一個(gè)DataSet或一個(gè)DataTable時(shí),所有這些信息就會被傳遞給serializer。被串行化的對象總是包含XML數(shù)據(jù),因此即使當(dāng)輸出流是二進(jìn)制的時(shí),最后的輸出結(jié)果仍然會很大。

你可以創(chuàng)建一個(gè)繼承DataTable或DataSet的新的可串行化的類來解決這個(gè)問題,并且更有效地保存ADO.NET對象。你必須用<Serizlizable()>屬性來標(biāo)記新類,即使父類是可以串行化的。實(shí)際上,串行性(serizlizability)并不是一個(gè)可以自動繼承的類屬性。你從DataTable或DataSet構(gòu)建的新類也可以實(shí)現(xiàn)ISerializable接口。當(dāng)然,你可以為新類選擇一個(gè)不同的串行化方案。一個(gè)簡單而有效的方法就是將DataTable類的所有成員映射到數(shù)組和值成員中。

運(yùn)用一個(gè)派生的類和一個(gè)自定義的串行化方案可以為一個(gè)DataSet對象節(jié)省多達(dá)80%的磁盤空間。節(jié)省的空間的比率取決于DataSet中的數(shù)據(jù)類型。你的數(shù)據(jù)越基于文本,節(jié)省的空間越多。然而,運(yùn)用二進(jìn)制的BLOB字段只可以節(jié)省大約25%的空間(下載一個(gè)完整的例子)。

9. 選擇一個(gè)適合你的數(shù)據(jù)的分頁機(jī)制
DataGrid服務(wù)器控件使我們可以更容易地在Web應(yīng)用程序中以長度可變的頁面來顯示數(shù)據(jù)了。該控件有綁定和格式化功能,它可以接受一個(gè)ADO.NET數(shù)據(jù)對象并為瀏覽器生成HTML代碼。出于性能的原因,在頁面的視圖狀態(tài),DataGrid并沒有緩存數(shù)據(jù)源的內(nèi)容。因此,當(dāng)返回頁面時(shí),你就必須填充grid。要實(shí)現(xiàn)這一點(diǎn)可以用兩種方法:在Web服務(wù)器上將數(shù)據(jù)源作為整體或一部分緩存起來,然后讀回;或者對每個(gè)請求從物理數(shù)據(jù)庫加載所需的記錄。如果你選擇第一種方法,那么數(shù)據(jù)就從存儲中只被讀取一次,保存在一個(gè)緩存中,并為以后的postback事件讀回。我們通常用內(nèi)存中的全局對象(如Session或Cache)來保存這個(gè)數(shù)據(jù)。我們用DataSet來搜集所有需要的數(shù)據(jù)并將它保存在內(nèi)存中。將一個(gè)DataSet對象保存在Session中同ADO中的線程含義并不一樣,但是通過減少Web服務(wù)器可用的內(nèi)存仍可以影響可擴(kuò)展性。

如果要顯示的數(shù)據(jù)是特定于session的,那么在每次返回頁面時(shí)加載記錄頁面就比用一個(gè)DataSet和ASP.NET全局對象來緩存數(shù)據(jù)要好。編寫得很好的SQL代碼可以將結(jié)果集分成許多頁,再加上DataGrid控件內(nèi)置的自定義分頁機(jī)制,我們就可以得到最佳的解決方案來保持ASP.NET應(yīng)用程序的可擴(kuò)展性和良好的性能了。

對于Windows應(yīng)用程序,我的建議正好相反。臺式應(yīng)用程序很適合應(yīng)用斷開的編程模式(DataSet和其它ADO.NET對象使這種模式變得更簡單了)。當(dāng)然,這并不意味著,你可以在客戶端無憂無慮地下載成千上萬的記錄。盡管你可以將ADO.NET對象用于任何種類的.NET應(yīng)用程序,但如何使用它們是隨具體情況的不同而不同的。

10. 訪問多個(gè)結(jié)果集
根據(jù)查詢的語法,你可以返回多個(gè)結(jié)果集。缺省情況下,data reader是位于第一個(gè)結(jié)果集上的。你可以用Read方法在當(dāng)前結(jié)果集中滾動查看記錄。在找到最后一個(gè)記錄時(shí),Read方法返回false,不再繼續(xù)讀取。你應(yīng)該用NextResult方法轉(zhuǎn)移到下一個(gè)結(jié)果集。如果沒有更多的需要讀的結(jié)果集了,那么該方法返回false。下面的代碼說明了如何在所有返回的結(jié)果集中訪問所有的記錄:Dim reader As SqlDataReader 
cmd.Connection.Open()
reader = cmd.ExecuteReader()
Do 
' Move through the first resultset
While reader.Read()
' access the row
End While
Loop While reader.NextResult()
reader.Close()
cmd.Connection.Close()




當(dāng)你讀一個(gè)行的內(nèi)容時(shí),可以通過索引或名稱來識別列。運(yùn)用索引可以更快,因?yàn)樘峁┱呖梢灾苯舆M(jìn)入到緩沖器中。如果你指定列名,提供者就用GetOrdinal方法將名稱轉(zhuǎn)換成相應(yīng)的索引,然后執(zhí)行基于索引的訪問。注意,對于SQL Server data reader來說,所有的GetXXX方法實(shí)際上都調(diào)用了相應(yīng)的GetSqlXXX方法。對于Oracle data reader來說,情況是類似的,本地?cái)?shù)據(jù)總是被寫進(jìn).NET Framework類型中。OracleDataReader類為它自己的內(nèi)部類型提供了一組私有的GetXXX方法。這些方法包括GetOracleBFile、GetOracleBinary和GetOracleDateTime等。相反,OLE DB和ODBC readers只有單獨(dú)的一組get方法。

.NET Framework 1.1版通過添加方法HasRows擴(kuò)展了data readers的編程接口,該方法返回一個(gè)Boolean值來說明是否有很多行需要讀。(這是ASP.NET 1.0的一個(gè)不足之處。)然而,該方法并沒有告訴我們有效的行的數(shù)量。同樣,也沒有方法或技巧使我們提前知道已經(jīng)返回了多少結(jié)果集。

在Oracle數(shù)據(jù)庫編程中,一個(gè)查詢或一個(gè)存儲過程返回的多個(gè)結(jié)果集是通過多個(gè)REF CURSOR對象處理的。有多少結(jié)果集,你就必須將多少輸出參數(shù)同命令關(guān)聯(lián)起來,以便NextResult方法可以用于Oracle數(shù)據(jù)庫。在命令文本中,一個(gè)ADO.NET結(jié)果集同一個(gè)Oracle REF CURSOR是一致的。輸出參數(shù)名必須與指針名匹配,它們的類型必須是OracleType.Cursor。例如,如果要運(yùn)行的存儲過程(或命令文本)引用了兩個(gè)指針(Employees和Orders),那么下面的代碼就說明了如何進(jìn)行設(shè)置以返回兩個(gè)結(jié)果集:Dim p1 As OracleParameter 
p1 = cmd.Parameters.Add("Employees", OracleType.Cursor)
p1.Direction = ParameterDirection.Output
Dim p2 As OracleParameter
p2 = cmd.Parameters.Add("Orders", OracleType.Cursor)
p2.Direction = ParameterDirection.Output




在上面的代碼中,cmd是一個(gè)OracleCommand對象,它指向一個(gè)命令或一個(gè)存儲過程。它執(zhí)行代碼,創(chuàng)建了兩個(gè)REF CURSOR,稱為Employees和Orders。REF CURSOR的名稱和ADO.NET輸出參數(shù)的名稱必須匹配。

ADO.NET對象模式包含兩個(gè)主要的部分——托管提供者和database-agnostic的容器類,如DataSet。托管提供者是數(shù)據(jù)源連接器的新類型;它們代替了基于COM的OLE DB提供者。到我寫這篇文章時(shí)為止,只有少數(shù)幾個(gè)托管提供者來連接商業(yè)DBMS。.NET Framework 1.1版只包含幾個(gè)本地提供者——用于SQL Server、Oracle和所有OLE DB的提供者和ODBC驅(qū)動程序。第三方的供應(yīng)商也支持MySQL并為Oracle提供了可供選擇的提供者。

ADO.NET看起來類似于ADO,而且托管提供者在結(jié)構(gòu)上同OLE DB提供者也是可以相比的。除了這些相似點(diǎn)外,在ADO.NET中進(jìn)行有效的編程還需要一套新的技巧和好的方法。在大多數(shù)情況下,你可以通過編寫代碼得到很多技巧,并積累對象模式方面的經(jīng)驗(yàn)。當(dāng)你在進(jìn)一步研究ADO.NET編程時(shí),記住我在本文中所講的這10個(gè)ADO.NET技巧吧。
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
6.2.4 DataSet對象
14.2.1 ADO.NET
ADO.net學(xué)習(xí)記錄 (一)
ADO.NET中5大對象簡介
ADO.NET數(shù)據(jù)庫訪問技術(shù)(二)
ADO.net中常用的對象介紹
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服