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

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

20、將全部預定的刪除在應用程序中本地存儲起來,然后再發(fā)出一條批處理指令調用,從數據源刪除它們。 雖然這樣做的確能提高性能,但是,當對DataSet中的數據更新進行管理時,可能會增加應用程序的簡單性。要保持簡潔,可能要在DataSet中為每個DataTable創(chuàng)建一個DataAdapter。 用多個表填充DataSet 假如用法批處理SQL語句檢索多個表并填充DataSet,第一個表用指定給Fill方法的表名命名。后面的表用指定給Fill方法的表名加上一個從1開頭并且增量為1的數字命名。例如,假如運行下面的代碼: 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表的數據放在名為“Customers”的DataTable中。來自Orders表的數據放在名為“Customers1”的DataTable中。 填充完DataSet之后,可以很簡單地將“Customers1”表的TableName屬性改為“Orders”。但是,后面的填充會導致“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獲得最佳性能的技巧,同時還回答了一些關于用法DataReader的常見問題。 1) 在訪問相關Command的任何輸出參數之前,必需關閉DataReader。 2) 完成讀數據之后總是要關閉DataReader。假如用法Connection只是用于返回DataReader,那么關閉DataReader之后立即關閉它。 另外一個顯式關閉Connect

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

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

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

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

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

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

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

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

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

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

35、s WHERE (LastName = LastName) OR (LastName IS NULL AND LastName IS NULL) 將Null作為參數值傳遞 對數據庫的指令中,當將空值作為參數值發(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í)行事務 ADO.NET的事務模型已經更改。在ADO中,當調用StartTransaction時,調用之后的任何更新操作都被視為是事務的一部分。但是,在ADO.NET中,當調用Connection .BeginTransaction時,會返回一個Transaction對象,需要將它與Command的Transaction屬性聯系起來。這種設計可以在一個單一連接上執(zhí)行多個根事務。假如未將Command.Transaction屬性設置

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

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

39、顯式地在開頭事務之前打開連接,并在提交之后關閉連接。例如: 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(); 始終關閉Connection和DataReader 完成對Connection或DataReader對象的用法后,總是顯式地關閉它們。盡管垃圾回收最終會清除對象并因此釋放連接和其他托管資源,但垃圾回收僅在需要時執(zhí)行。因此,確保任何珍貴的資源被顯式釋放仍舊是您的責任。并且,沒有顯式關閉的Connections可能不會返回到池中

44、。例如,一個超出作用范圍卻沒有顯式關閉的連接,只有當連接池大小達到最大并且連接仍舊有效時,才會被返回到連接池中。 注不要在類的Finalize方法中對Connection、DataReader或任何其他托管對象調用Close或Dispose。最終完成的時候,僅釋放類自己挺直擁有的非托管資源。假如類沒有任何非托管資源,就不要在類定義中包含Finalize方法。 在C#中用法“Using”語句 對于C#程序員來說,確保始終關閉Connection和DataReader對象的一個便利的方法就是用法using語句。using語句在離開自己的作用范圍時,會自動調用被“用法”的對象的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屬性 假如連接已經打開,OleDbConnection.State屬性會對DBPROP_CONNECTIONSTATUS屬性的DATASOURCEINFO屬性集執(zhí)行本地OLE DB調用IDBProperties.GetProperties,這可能會導致對數據源的往返行程。也就是說,

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

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

溫馨提示

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

最新文檔

評論

0/150

提交評論