ADO.NET有用閱歷介紹__第1頁
ADO.NET有用閱歷介紹__第2頁
ADO.NET有用閱歷介紹__第3頁
ADO.NET有用閱歷介紹__第4頁
ADO.NET有用閱歷介紹__第5頁
免費預(yù)覽已結(jié)束,剩余25頁可下載查看

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、ADO.NET有用閱歷介紹_ ADO.NET作為微軟最新的數(shù)據(jù)訪問技術(shù),已經(jīng)在企業(yè)開發(fā)中得到了廣泛的應(yīng)用。對于一線的開發(fā)人員來說,把握基本的概念和技術(shù)之后,提高應(yīng)用水平和解決實際問題的最有效手段,莫過于相互溝通彼此的最佳時間閱歷閱歷。在這篇文章中,兩位ADO.NET專家向讀者毫無保留地、詳盡地介紹了許多有用閱歷。 簡介 本文為您供應(yīng)了在Microsoft ADO.NET應(yīng)用程序中實現(xiàn)和獲得最佳性能、可伸縮性以及功能的最佳解決方案;同時也講解并描述了用法ADO.NET中可用對象的最佳實踐;并提出一些有助于優(yōu)化ADO.NET應(yīng)用程序設(shè)計的建議。 .NET框架數(shù)據(jù)供應(yīng)程序 .NET框架中的數(shù)據(jù)供應(yīng)程

2、序(Data PRovider)在應(yīng)用程序和數(shù)據(jù)源之間起到橋梁作用。.NET框架數(shù)據(jù)供應(yīng)程序能夠從數(shù)據(jù)源中返回查詢結(jié)果、對數(shù)據(jù)源執(zhí)行指令、將DataSet中的更改傳播給數(shù)據(jù)源。本文包括有關(guān)哪個.NET框架數(shù)據(jù)供應(yīng)程序是最適合您需要的一些技巧。 用法哪個.NET框架數(shù)據(jù)供應(yīng)程序? 為了使您的應(yīng)用程序獲得最佳性能,請用法最適合您的數(shù)據(jù)源的.NET框架數(shù)據(jù)供應(yīng)程序。有很多數(shù)據(jù)供應(yīng)程序可供您的應(yīng)用程序選用。 連接到SQL Server 7.0或更高版本 為了在連接到Microsoft SQL Server 7.0或更高版本時獲得最佳性能,請用法SQL Server .NET數(shù)據(jù)供應(yīng)程序。SQL Ser

3、ver .NET數(shù)據(jù)供應(yīng)程序的設(shè)計目的就在于不通過任何附加技術(shù)層就可以挺直訪問SQL Server。 連接到ODBC數(shù)據(jù)源 ODBC .NET數(shù)據(jù)供應(yīng)程序可在Microsoft.Data.ODBC命名空間中找到,它的體系結(jié)構(gòu)與用于SQL Server和OLE DB的.NET數(shù)據(jù)供應(yīng)程序相同。ODBC .NET數(shù)據(jù)供應(yīng)程序遵循命名商定-以“ODBC”為前綴(例如,OdbcConnection),并用法標(biāo)準(zhǔn)ODBC連接字符串。 用法DataReader、DataSet、DataAdapter和DataView ADO.NET供應(yīng)以下兩個對象,用于檢索關(guān)系數(shù)據(jù)并將其存儲在內(nèi)存中:DataSet和Da

4、taReader。DataSet供應(yīng)一個內(nèi)存中數(shù)據(jù)的關(guān)系表示形式,一整套包括一些表在內(nèi)的數(shù)據(jù)(這些表包含數(shù)據(jù)、對數(shù)據(jù)進行排序并約束數(shù)據(jù)),以及表之間的關(guān)系。DataReader供應(yīng)一個來自數(shù)據(jù)庫的快速、僅向前、只讀數(shù)據(jù)流。 當(dāng)用法DataSet時,常常會利用DataAdapter(也可能是CommandBuilder)與數(shù)據(jù)源進行交互。當(dāng)用法DataSet時,也可以利用DataView對DataSet中的數(shù)據(jù)應(yīng)用排序和篩選。也可以從DataSet繼承,創(chuàng)建強類型DataSet,用于將表、行和列作為強類型對象屬性公開。 下列主題包括的信息涉及:用法DataSet或DataReader的最佳時機、

5、如何優(yōu)化訪問它們所包含數(shù)據(jù)、以及如何優(yōu)化用法DataAdapter(包括CommandBuilder)和DataView的技巧。 DataSet與DataReader 當(dāng)設(shè)計應(yīng)用程序時,要考慮應(yīng)用程序所需功能的等級,以確定用法DataSet或者是DataReader。 要通過應(yīng)用程序執(zhí)行以下操作,就要用法DataSet: 1) 在結(jié)果的多個離散表之間進行導(dǎo)航。 2) 操作來自多個數(shù)據(jù)源(例如,來自多個數(shù)據(jù)庫、一個xml文件和一個電子表格的混合數(shù)據(jù))的數(shù)據(jù)。 3) 在各層之間交換數(shù)據(jù)或用法XML Web服務(wù)。與DataReader不同的是,DataSet能傳遞給遠程客戶端。 4) 重用同樣的記錄

6、集合,以便通過緩存獲得性能改善(例如排序、搜索或篩選數(shù)據(jù))。 5) 每條記錄都需要執(zhí)行大量處理。對用法DataReader返回的每一行進行擴展處理睬延長服務(wù)于DataReader的連接的必要時間,這影響了性能。 6) 用法XML操作對數(shù)據(jù)進行操作,例如可擴展樣式表語言轉(zhuǎn)換(XSLT轉(zhuǎn)換)或XPath查詢。 對于下列狀況,要在應(yīng)用程序中用法DataReader: 1) 不需要緩存數(shù)據(jù)。 2) 要處理的結(jié)果集太大,內(nèi)存中放不下。 3) 一旦需要以僅向前、只讀方式快速訪問數(shù)據(jù)。 注填充DataSet時,DataAdapter用法DataReader。因此,用法DataAdapter取代DataSet

7、提升的性能表現(xiàn)為節(jié)約了DataSet占用內(nèi)存和填充DataSet需要的循環(huán)。一般來說,此性能提升只是象征性的,因此,設(shè)計決策應(yīng)以所需功能為基礎(chǔ)。 用法強類型DataSet的好處 DataSet的另一個好處是可被繼承以創(chuàng)建一個強類型DataSet。強類型DataSet的好處包括設(shè)計時類型檢查,以及Microsoft Visual Studio.NET用于強類型DataSet語句結(jié)束所帶來的好處。修改了DataSet的架構(gòu)或關(guān)系結(jié)構(gòu)后,就可以創(chuàng)建一個強類型DataSet,將行和列作為對象的屬性公開,而不是作為集合中的項公開。例如,不公開客戶表中行的姓名列,而公開Customer對象的Name屬性。

8、類型化DataSet從DataSet類派生,因此不會犧牲DataSet的任何功能。也就是說,類型化DataSet仍能遠程訪問,并作為數(shù)據(jù)綁定控件(例如DataGrid)的數(shù)據(jù)源供應(yīng)。假如架構(gòu)事先不行知,仍能受益于通用DataSet的功能,但卻不能受益于強類型DataSet的附加功能。 處理強類型DataSet中的空引用 用法強類型DataSet時,可以用法DataSet的XML架構(gòu)定義語言(XSD)架構(gòu)來確保強類型DataSet可以正確處理空引用。nullValue標(biāo)識符使您可用一個指定的值String.Empty代替DBNull、保留空引用或引發(fā)特別。選擇哪個選項取決于應(yīng)用程序的上下文。默認

9、狀況下,假如遇到空引用,就會引發(fā)特別。 刷新DataSet中的數(shù)據(jù) 假如想用服務(wù)器上的更新值刷新DataSet中的值,就用法DataAdapter.Fill。假如有在DataTable上定義的主鍵,DataAdapter.Fill會依據(jù)主鍵進行新行匹配,并且當(dāng)更改到現(xiàn)有行時應(yīng)用服務(wù)器上的值。即使刷新之前修改了這些數(shù)據(jù),刷新行的RowState仍被設(shè)置為Unchanged。留意,假如沒有為DataTable定義主鍵,DataAdapter.Fill就用可能重復(fù)的主鍵值添加新行。 假如想用來自服務(wù)器的當(dāng)前值刷新表,并同時保留對表中的行所做的任何更改,必需首先用DataAdapter.Fill填充表

10、,并填充一個新的DataTable,然后用preserveChanges值true將DataTable合并到DataSet之中。 在DataSet中搜索數(shù)據(jù) 在DataSet中查詢與特定條件相匹配的行時,可以利用基于索引的查找提高搜干脆能。當(dāng)將PrimaryKey值賦給DataTable時,會創(chuàng)建一個索引。當(dāng)給DataTable創(chuàng)建DataView時,也會創(chuàng)建一個索引。下面是一些利用基于索引進行查找的技巧。 1) 假如對組成DataTable的PrimaryKey的列進行查詢,要用法DataTable.Rows.Find而不是DataTable.Select。 2) 對于涉及到非主鍵列的查詢,

11、可以用法DataView為數(shù)據(jù)的多個查詢提高性能。當(dāng)將排序挨次應(yīng)用到DataView時,就會建立一個搜索時用法的索引。DataView公開Find和FindRows方法,以便查詢基礎(chǔ)DataTable中的數(shù)據(jù)。 3) 假如不需要表的排序視圖,仍可以通過為DataTable創(chuàng)建DataView來利用基于索引的查找。留意,只有對數(shù)據(jù)執(zhí)行多個查詢操作時,這樣才會帶來好處。假如只執(zhí)行單一查詢,創(chuàng)建索引所需要的處理就會降低用法索引所帶來的性能提升。 DataView構(gòu)造 假如創(chuàng)建了DataView,并且修改了Sort、RowFilter或RowStateFilter屬性,DataView就會為基礎(chǔ)Dat

12、aTable中的數(shù)據(jù)建立索引。創(chuàng)建DataView對象時,要用法DataView構(gòu)造函數(shù),它用Sort、RowFilter和RowStateFilter值作為構(gòu)造函數(shù)參數(shù)(與基礎(chǔ)DataTable一起)。結(jié)果是創(chuàng)建了一次索引。創(chuàng)建一個“空”DataView并隨后設(shè)置Sort、RowFilter或RowStateFilter屬性,會導(dǎo)致索引至少創(chuàng)建兩次。 ADO.NET可以顯式掌握從數(shù)據(jù)源中返回什么樣的數(shù)據(jù),以及在DataSet中本地緩存多少數(shù)據(jù)。對查詢結(jié)果的分頁沒有唯一的答案,但下面有一些設(shè)計應(yīng)用程序時應(yīng)當(dāng)考慮的技巧。 1) 避開用法帶有startRecord和maxRecords值的Data

13、Adapter.Fill重載。當(dāng)以這種方式填充DataSet時,只有maxRecords參數(shù)(從startRecord參數(shù)標(biāo)識的記錄開頭)指定的記錄數(shù)量用于填充DataSet,但無論如何總是返回完整的查詢。這就會引起不必要的處理,用于讀取“不需要的”記錄;而且為了返回附加記錄,會耗盡不必要的服務(wù)器資源。 2) 用于每次只返回一頁記錄的技術(shù)是創(chuàng)建SQL語句,將WHERE子句以及ORDER BY子句和TOP謂詞組合起來。此技術(shù)取決于存在一種可唯一標(biāo)識每一行的方法。當(dāng)掃瞄下一頁記錄時,修改WHERE子句使之包含全部唯一標(biāo)識符大于當(dāng)前頁最終一個唯一標(biāo)識符的記錄。當(dāng)掃瞄上一頁記錄時,修改WHERE子句使

14、之返回全部唯一標(biāo)識符小于當(dāng)前頁第一個唯一標(biāo)識符的記錄。兩種查詢都只返回記錄的TOP頁。當(dāng)掃瞄上一頁時,需要以降序為結(jié)果排序。這將有效地返回查詢的最終一頁(假如需要,顯示之前或許要重新排序結(jié)果)。 3) 另一項每次只返回一頁記錄的技術(shù)是創(chuàng)建SQL語句,將TOP謂詞和嵌入式SELECT語句的用法結(jié)合在一起。此技術(shù)并不依靠于存在一種可唯一標(biāo)識每一行的方法。用法這項技術(shù)的第一步是將所需頁的數(shù)量與頁大小相乘。然后將結(jié)果傳遞給SQL Query的TOP謂詞,該查詢以升序排列。再將此查詢嵌入到另一個查詢中,后者從降序排列的嵌入式查詢結(jié)果中選擇TOP頁大小。實質(zhì)上,返回的是嵌入式查詢的最終一頁。例如,要返回查

15、詢結(jié)果的第三頁(頁大小是10),應(yīng)當(dāng)書寫如下所示的指令: SELECT TOP 10 * FROM (SELECT TOP 30 * FROM Customers ORDER BY Id ASC) AS Table1 ORDER BY Id DESC 留意:從查詢中返回的結(jié)果頁以降序顯示。假如需要,應(yīng)當(dāng)重新排序。 1) 假如數(shù)據(jù)不常常變動,可以在DataSet中本地維護一個記錄緩存,以此提高性能。例如,可以在本地DataSet中存儲10頁有用的數(shù)據(jù),并且只有當(dāng)用戶掃瞄超出緩存第一頁和最終一頁時,才從數(shù)據(jù)源中查詢新數(shù)據(jù)。 用架構(gòu)填充DataSet 當(dāng)用數(shù)據(jù)填充DataSet時,DataAdapt

16、er.Fill方法用法DataSet的現(xiàn)有架構(gòu),并用法從SelectCommand返回的數(shù)據(jù)填充它。假如在DataSet中沒有表名與要被填充的表名相匹配,F(xiàn)ill方法就會創(chuàng)建一個表。默認狀況下,F(xiàn)ill僅定義列和列類型。 通過設(shè)置DataAdapter的MissingSchemaAction屬性,可以重寫Fill的默認行為。例如,要讓Fill創(chuàng)建一個表架構(gòu),并且還包括主鍵信息、唯一約束、列屬性、是否允許為空、最大列長度、只讀列和自動增量的列,就要將DataAdapter.MissingSchemaAction指定為MissingSchemaAction.AddWithKey?;蛘?,在調(diào)用Dat

17、aAdapter.Fill前,可以調(diào)用DataAdapter.FillSchema來確保當(dāng)填充DataSet時架構(gòu)已到位。 對FillSchema的調(diào)用會產(chǎn)生一個到服務(wù)器的額外行程,用于檢索附加架構(gòu)信息。為了獲得最佳性能,需要在調(diào)用Fill之前指定DataSet的架構(gòu),或者設(shè)置DataAdapter的MissingSchemaAction。 用法CommandBuilder的最佳實踐 假設(shè)SelectCommand執(zhí)行單一表SELECT,CommandBuilder就會以DataAdapter的SelectCommand屬性為基礎(chǔ)自動生成DataAdapter的InsertCommand、Up

18、dateCommand、和DeleteCommand屬性。下面是為獲得最佳性能而用法CommandBuilder的一些技巧。 1) CommandBuilder的用法應(yīng)當(dāng)限制在設(shè)計時或即席方案中。生成DataAdapter指令屬性所必需的處理睬影響性能。假如預(yù)先知道INSERT/UPDATE/DELETE語句的內(nèi)容,就顯式設(shè)置它們。一個比較好的設(shè)計技巧是,為INSERT/UPDATE/DELETE指令創(chuàng)建存儲過程并顯式配置DataAdapter指令屬性以用法它們。 2) CommandBuilder用法DataAdapter的SelectCommand屬性確定其他指令屬性的值。假如DataAd

19、apter的SelectCommand本身曾經(jīng)更改過,確保調(diào)用RefreshSchema以更新指令屬性。 3) 假如DataAdapter指令屬性為空(指令屬性默認狀況下為空),CommandBuilder僅僅為它生成一條指令。假如顯式設(shè)置了指令屬性,CommandBuilder不會重寫它。假如盼望CommandBuilder為以前已經(jīng)設(shè)置過的指令屬性生成指令,就將指令屬性設(shè)置為空。 批處理SQL語句 許多數(shù)據(jù)庫支持將多條指令合并或批處理成一條單一指令執(zhí)行。例如,SQL Server使您可以用分號“;”分隔指令。將多條指令合并成單一指令,能削減到服務(wù)器的行程數(shù),并提高應(yīng)用程序的性能。例如,可以

20、將全部預(yù)定的刪除在應(yīng)用程序中本地存儲起來,然后再發(fā)出一條批處理指令調(diào)用,從數(shù)據(jù)源刪除它們。 雖然這樣做的確能提高性能,但是,當(dāng)對DataSet中的數(shù)據(jù)更新進行管理時,可能會增加應(yīng)用程序的簡單性。要保持簡潔,可能要在DataSet中為每個DataTable創(chuàng)建一個DataAdapter。 用多個表填充DataSet 假如用法批處理SQL語句檢索多個表并填充DataSet,第一個表用指定給Fill方法的表名命名。后面的表用指定給Fill方法的表名加上一個從1開頭并且增量為1的數(shù)字命名。例如,假如運行下面的代碼: Visual Basic Dim da As SqlDataAdapter = New

21、 SqlDataAdapter(SELECT * FROM Customers; SELECT * FROM Orders;, myConnection) Dim ds As DataSet = New DataSet() da.Fill(ds, Customers) /C# SqlDataAdapter da = new SqlDataAdapter(SELECT * FROM Customers; SELECT * FROM Orders;, myConnection); DataSet ds = new DataSet(); da.Fill(ds, Customers); 來自Custo

22、mers表的數(shù)據(jù)放在名為“Customers”的DataTable中。來自O(shè)rders表的數(shù)據(jù)放在名為“Customers1”的DataTable中。 填充完DataSet之后,可以很簡單地將“Customers1”表的TableName屬性改為“Orders”。但是,后面的填充會導(dǎo)致“Customers”表被重新填充,而“Orders”表會被忽視,并創(chuàng)建另外一個“Customers1”表。為了對這種狀況作出補救,創(chuàng)建一個DataTableMapping,將“Customers1”映射到“Orders”,并為其他后面的表創(chuàng)建其他的表映射。例如: Visual Basic Dim da As S

23、qlDataAdapter = New SqlDataAdapter(SELECT * FROM Customers; SELECT * FROM Orders;, myConnection) da.TableMappings.Add(Customers1, Orders) Dim ds As DataSet = New DataSet() da.Fill(ds, Customers) /C# SqlDataAdapter da = new SqlDataAdapter(SELECT * FROM Customers; SELECT * FROM Orders;, myConnection);

24、 da.TableMappings.Add(Customers1, Orders); DataSet ds = new DataSet(); da.Fill(ds, Customers); 用法DataReader 下面是一些用法DataReader獲得最佳性能的技巧,同時還回答了一些關(guān)于用法DataReader的常見問題。 1) 在訪問相關(guān)Command的任何輸出參數(shù)之前,必需關(guān)閉DataReader。 2) 完成讀數(shù)據(jù)之后總是要關(guān)閉DataReader。假如用法Connection只是用于返回DataReader,那么關(guān)閉DataReader之后立即關(guān)閉它。 另外一個顯式關(guān)閉Connect

25、ion的方法是將CommandBehavior.CloseConnection傳遞給ExecuteReader方法,以確保相關(guān)的連接在關(guān)閉DataReader時被關(guān)閉。假如從一個方法返回DataReader,而且不能掌握DataReader或相關(guān)連接的關(guān)閉,則這樣做格外有用。 1) 不能在層之間遠程訪問DataReader。DataReader是為已連接好的數(shù)據(jù)訪問設(shè)計的。 2) 當(dāng)訪問列數(shù)據(jù)時,用法類型化訪問器,例如,GetString、GetInt32等。這使您不用進行將GetValue返回的Object強制轉(zhuǎn)換成特定類型所需的處理。 3) 一個單一連接每次只能打開一個DataReader

26、。在ADO中,假如打開一個單一連接,并且懇求兩個用法只進、只讀游標(biāo)的記錄集,那么ADO會在游標(biāo)生存期內(nèi)隱式打開其次個、未池化的到數(shù)據(jù)存儲區(qū)的連接,然后再隱式關(guān)閉該連接。對于ADO.NET,“隱秘”完成的動作很少。假如想在相同的數(shù)據(jù)存儲區(qū)上同時打開兩個DataReaders,就必需顯式創(chuàng)建兩個連接,每個DataReader一個。這是ADO.NET為池化連接的用法供應(yīng)更多掌握的一種方法。 4) 默認狀況下,DataReader每次Read時都要將整行加載到內(nèi)存。這允許在當(dāng)前行內(nèi)隨機訪問列。假如不需要這種隨機訪問,為了提高性能,就將CommandBehavior.Sequentialaccess傳遞

27、給ExecuteReader調(diào)用。這將DataReader的默認行為更改為僅在懇求時將數(shù)據(jù)加載到內(nèi)存。留意,CommandBehavior.SequentialAccess要求挨次訪問返回的列。也就是說,一旦讀過返回的列,就不能再讀它的值了。 5) 假如已經(jīng)完成讀取來自DataReader的數(shù)據(jù),但仍舊有大量掛起的未讀結(jié)果,就在調(diào)用DataReader的Close之前先調(diào)用Command的Cancel。調(diào)用DataReader的Close會導(dǎo)致在關(guān)閉游標(biāo)之前檢索掛起的結(jié)果并清空流。調(diào)用Command的Cancel會放棄服務(wù)器上的結(jié)果,這樣,DataReader在關(guān)閉的時候就不必讀這些結(jié)果。假如

28、要從Command返回輸出參數(shù),還要調(diào)用Cancel放棄它們。假如需要讀取任何輸出參數(shù),不要調(diào)用Command的Cancel,只要調(diào)用DataReader的Close即可。 二進制大對象(BLOB) 用DataReader檢索二進制大對象(BLOB)時,應(yīng)當(dāng)將CommandBehavior.SequentialAccess傳遞給ExecuteReader方法調(diào)用。由于DataReader的默認行為是每次Read都將整行加載到內(nèi)存,又由于BLOB值可能特別大,所以結(jié)果可能由于單個BLOB而使大量內(nèi)存被用光。SequentialAccess將DataReader的行為設(shè)置為只加載懇求的數(shù)據(jù)。然后還

29、可以用法GetBytes或GetChars掌握每次加載多少數(shù)據(jù)。 記住,用法SequentialAccess時,不能不按挨次訪問DataReader返回的不同字段。也就是說,假如查詢返回三列,其中第三列是BLOB,并且想訪問前兩列中的數(shù)據(jù),就必需在訪問BLOB數(shù)據(jù)之前先訪問第一列的值,然后訪問其次列的值。這是由于現(xiàn)在數(shù)據(jù)是挨次返回的,并且DataReader一旦讀過該數(shù)據(jù),該數(shù)據(jù)就不再可用。 用法指令 ADO.NET供應(yīng)了幾種指令執(zhí)行的不同方法以及優(yōu)化指令執(zhí)行的不同選項。下面包括一些技巧,它們是關(guān)于選擇最佳指令執(zhí)行以及如何提高執(zhí)行指令的性能。 用法OleDbCommand的最佳實踐 不同.NE

30、T框架數(shù)據(jù)供應(yīng)程序之間的指令執(zhí)行被盡可能標(biāo)準(zhǔn)化了。但是,數(shù)據(jù)供應(yīng)程序之間仍舊存在差異。下面給出一些技巧,可微調(diào)用于OLE DB的.NET框架數(shù)據(jù)供應(yīng)程序的指令執(zhí)行。 1) 根據(jù)ODBC CALL語法用法CommandType.Text調(diào)用存儲過程。用法CommandType.StoredProcedure只是隱秘地生成ODBC CALL語法。 2) 肯定要設(shè)置OleDbParameter的類型、大小(假如適用)、以及精度和范圍(假如參數(shù)類型是numeric或decimal)。留意,假如不顯式供應(yīng)參數(shù)信息,OleDbCommand會為每個執(zhí)行指令重新創(chuàng)建OLE DB參數(shù)訪問器。 用法SqlCom

31、mand的最佳實踐 用法SqlCommand執(zhí)行存儲過程的快速提示:假如調(diào)用存儲過程,將SqlCommand的CommandType屬性指定為StoredProcedure的CommandType。這樣通過將該指令顯式標(biāo)識為存儲過程,就不需要在執(zhí)行之前分析指令。 用法Prepare方法 對于重復(fù)作用于數(shù)據(jù)源的參數(shù)化指令,Command.Prepare方法能提高性能。Prepare指示數(shù)據(jù)源為多次調(diào)用優(yōu)化指定的指令。要想有效利用Prepare,需要徹底理解數(shù)據(jù)源是如何響應(yīng)Prepare調(diào)用的。對于一些數(shù)據(jù)源(例如SQL Server 2021),指令是隱式優(yōu)化的,不必調(diào)用Prepare。對于其他

32、(例如SQL Server 7.0)數(shù)據(jù)源,Prepare會比較有效。 顯式指定架構(gòu)和元數(shù)據(jù) 只要用戶沒有指定元數(shù)據(jù)信息,ADO.NET的很多對象就會推斷元數(shù)據(jù)信息。下面是一些示例: 1) DataAdapter.Fill方法,假如DataSet中沒有表和列,DataAdapter.Fill方法會在DataSet中創(chuàng)建表和列。 2) CommandBuilder,它會為單表SELECT指令生成DataAdapter指令屬性。 3) CommandBuilder.DeriveParameters,它會填充Command對象的Parameters集合。 但是,每次用到這些特性,都會有性能損失。建議

33、將這些特性主要用于設(shè)計時和即席應(yīng)用程序中。在可能的狀況下,顯式指定架構(gòu)和元數(shù)據(jù)。其中包括在DataSet中定義表和列、定義DataAdapter的Command屬性、以及為Command定義Parameter信息。 ExecuteScalar和ExecuteNonQuery 假如想返回像Count(*)、Sum(Price)或Avg(Quantity)的結(jié)果那樣的單值,可以用法Command.ExecuteScalar。ExecuteScalar返回第一行第一列的值,將結(jié)果集作為標(biāo)量值返回。由于單獨一步就能完成,所以ExecuteScalar不僅簡化了代碼,還提高了性能;要是用法DataRea

34、der就需要兩步才能完成(即,ExecuteReader+取值)。 用法不返回行的SQL語句時,例如修改數(shù)據(jù)(例如INSERT、UPDATE或DELETE)或僅返回輸出參數(shù)或返回值,請用法ExecuteNonQuery。這避開了用于創(chuàng)建空DataReader的任何不必要處理。 測試Null 假如表(在數(shù)據(jù)庫中)中的列允許為空,就不能測試參數(shù)值是否“等于”空。相反,需要寫一個WHERE子句,測試列和參數(shù)是否都為空。下面的SQL語句返回一些行,它們的LastName列等于賦給LastName參數(shù)的值,或者LastName列和LastName參數(shù)都為空。 SELECT * FROM Customer

35、s WHERE (LastName = LastName) OR (LastName IS NULL AND LastName IS NULL) 將Null作為參數(shù)值傳遞 對數(shù)據(jù)庫的指令中,當(dāng)將空值作為參數(shù)值發(fā)送時,不能用法null(Visual Basic .NET中為Nothing)。而需要用法DBNull.Value。例如: Visual Basic Dim param As SqlParameter = New SqlParameter(Name, SqlDbType.NVarChar, 20) param.Value = DBNull.Value /C# SqlParameter p

36、aram = new SqlParameter(Name, SqlDbType.NVarChar, 20); param.Value = DBNull.Value; 執(zhí)行事務(wù) ADO.NET的事務(wù)模型已經(jīng)更改。在ADO中,當(dāng)調(diào)用StartTransaction時,調(diào)用之后的任何更新操作都被視為是事務(wù)的一部分。但是,在ADO.NET中,當(dāng)調(diào)用Connection .BeginTransaction時,會返回一個Transaction對象,需要將它與Command的Transaction屬性聯(lián)系起來。這種設(shè)計可以在一個單一連接上執(zhí)行多個根事務(wù)。假如未將Command.Transaction屬性設(shè)置

37、為一個針對相關(guān)的Connection而啟動的Transaction,那么Command就會失敗并引發(fā)特別。 即將發(fā)布的.NET框架將使您可以在現(xiàn)有的分布式事務(wù)中手動登記。這對于對象池方案來說很抱負;在該方案中,一個池對象打開一次連接,但是在多個獨立的事務(wù)中都涉及到該對象。.NET框架1.0發(fā)行版中這一功能并不行用。 用法連接 高性能應(yīng)用程序與用法中的數(shù)據(jù)源保持最短時間的連接,并且利用性能增加技術(shù),例如連接池。下面的主題供應(yīng)一些技巧,有助于在用法ADO.NET連接到數(shù)據(jù)源時獲得更好的性能。 連接池 用于ODBC的SQL Server、OLE DB和.NET框架數(shù)據(jù)供應(yīng)程序隱式緩沖連接。通過在連接

38、字符串中指定不同的屬性值,可以掌握連接池的行為。 用DataAdapter優(yōu)化連接 DataAdapter的Fill和Update方法在連接關(guān)閉的狀況下自動打開為相關(guān)指令屬性指定的連接。假如Fill或Update方法打開了連接,F(xiàn)ill或Update將在操作完成的時候關(guān)閉它。為了獲得最佳性能,僅在需要時將與數(shù)據(jù)庫的連接保持為打開。同時,削減打開和關(guān)閉多操作連接的次數(shù)。 假如只執(zhí)行單個的Fill或Update方法調(diào)用,建議允許Fill或Update方法隱式打開和關(guān)閉連接。假如對Fill和Update調(diào)用有許多,建議顯式打開連接,調(diào)用Fill和Update,然后顯式關(guān)閉連接。 另外,當(dāng)執(zhí)行事務(wù)時,

39、顯式地在開頭事務(wù)之前打開連接,并在提交之后關(guān)閉連接。例如: Visual Basic Public Sub RunSqlTransaction(da As SqlDataAdapter, myConnection As SqlConnection, ds As DataSet) myConnection.Open() Dim myTrans As SqlTransaction = myConnection.BeginTransaction() myCommand.Transaction = myTrans Try da.Update(ds) myTrans.Commit() Console.W

40、riteLine(Update successful.) Catch e As Exception Try myTrans.Rollback() Catch ex As SqlException If Not myTrans.Connection Is Nothing Then Console.WriteLine(An exception of type ex.GetType().ToString() was encountered while attempting to roll back the transaction.) End If End Try Console.WriteLine(

41、An exception of type e.GetType().ToString() was encountered.) Console.WriteLine(Update failed.) End Try myConnection.Close() End Sub /C# public void RunSqlTransaction(SqlDataAdapter da, SqlConnection myConnection, DataSet ds) myConnection.Open(); SqlTransaction myTrans = myConnection.BeginTransactio

42、n(); myCommand.Transaction = myTrans; try da.Update(ds); myCommand.Transaction.Commit(); Console.WriteLine(Update successful.); catch(Exception e) try myTrans.Rollback(); catch (SqlException ex) if (myTrans.Connection != null) Console.WriteLine(An exception of type + ex.GetType() + was encountered w

43、hile attempting to roll back the transaction.); Console.WriteLine(e.ToString(); Console.WriteLine(Update failed.); myConnection.Close(); 始終關(guān)閉Connection和DataReader 完成對Connection或DataReader對象的用法后,總是顯式地關(guān)閉它們。盡管垃圾回收最終會清除對象并因此釋放連接和其他托管資源,但垃圾回收僅在需要時執(zhí)行。因此,確保任何珍貴的資源被顯式釋放仍舊是您的責(zé)任。并且,沒有顯式關(guān)閉的Connections可能不會返回到池中

44、。例如,一個超出作用范圍卻沒有顯式關(guān)閉的連接,只有當(dāng)連接池大小達到最大并且連接仍舊有效時,才會被返回到連接池中。 注不要在類的Finalize方法中對Connection、DataReader或任何其他托管對象調(diào)用Close或Dispose。最終完成的時候,僅釋放類自己挺直擁有的非托管資源。假如類沒有任何非托管資源,就不要在類定義中包含F(xiàn)inalize方法。 在C#中用法“Using”語句 對于C#程序員來說,確保始終關(guān)閉Connection和DataReader對象的一個便利的方法就是用法using語句。using語句在離開自己的作用范圍時,會自動調(diào)用被“用法”的對象的Dispose。例如:

45、 /C# string connString = Data Source=localhost;Integrated Security=SSPI;Initial Catalog=Northwind; using (SqlConnection conn = new SqlConnection(connString) SqlCommand cmd = conn.CreateCommand(); cmd.CommandText = SELECT CustomerId, CompanyName FROM Customers; conn.Open(); using (SqlDataReader dr =

46、cmd.ExecuteReader() while (dr.Read() Console.WriteLine(0 1, dr.GetString(0), dr.GetString(1); Using語句不能用于Microsoft Visual Basic .NET。 避開訪問OleDbConnection.State屬性 假如連接已經(jīng)打開,OleDbConnection.State屬性會對DBPROP_CONNECTIONSTATUS屬性的DATASOURCEINFO屬性集執(zhí)行本地OLE DB調(diào)用IDBProperties.GetProperties,這可能會導(dǎo)致對數(shù)據(jù)源的往返行程。也就是說,

47、檢查State屬性的代價可能很高。所以僅在需要時檢查State屬性。假如需要常常檢查該屬性,監(jiān)聽OleDbConnection的StateChange大事可能會使應(yīng)用程序的性能好一些。 與XML集成 ADO.NET在DataSet中供應(yīng)了廣泛的XML集成,并公開了SQL Server 2021及其更高版本供應(yīng)的部分XML功能。還可以用法SQLXML 3.0廣泛地訪問SQL Server 2021及其更高版本中的XML功能。下面是用法XML和ADO.NET的技巧和信息。 DataSet和XML DataSet與XML緊密集成,并供應(yīng)如下功能: 1) 從XSD架構(gòu)中加載DataSet的架構(gòu)或關(guān)系型

48、結(jié)構(gòu)。 2) 從XML加載DataSet的內(nèi)容。 3) 假如沒有供應(yīng)架構(gòu),可以從XML文檔的內(nèi)容推斷出DataSet的架構(gòu)。 4) 將DataSet的架構(gòu)寫為XSD架構(gòu)。 5) 將DataSet的內(nèi)容寫為XML。 6) 同步訪問用法DataSet的數(shù)據(jù)的關(guān)系表示,以及用法XmlDataDocument的數(shù)據(jù)的層次表示。 注可以用法這種同步將XML功能(例如,XPath查詢和XSLT轉(zhuǎn)換)應(yīng)用到DataSet中的數(shù)據(jù),或者在保留原始XML保真度的前提下為XML文檔中數(shù)據(jù)的全部或其中一個子集供應(yīng)關(guān)系視圖。 架構(gòu)推斷 從XML文件加載DataSet時,可以從XSD架構(gòu)加載DataSet架構(gòu),或者在加載數(shù)據(jù)前預(yù)定義表和列。假如沒有可用的XSD架構(gòu),而且不知道為XML文件的內(nèi)容定義哪些表和列,就可以在XML文檔結(jié)構(gòu)的基礎(chǔ)上對架構(gòu)進行推斷。 架構(gòu)推斷作為遷移工具很有用,但應(yīng)只限于設(shè)計階段應(yīng)用程序,這是由于推斷處理有如下限制。 1) 對架構(gòu)的推斷會引入影響應(yīng)用程序性能的附加處理。 2) 全部推斷列的類型都是字符串。 3) 推斷處理不具有確定性。也就是說,它是基于XML文件內(nèi)容的,而不是預(yù)定的架構(gòu)。因此,對于兩個

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論