日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

Enterprise Library 4 数据访问应用程序块

發(fā)布時(shí)間:2023/11/27 生活经验 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Enterprise Library 4 数据访问应用程序块 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

Enterprise Library 數(shù)據(jù)訪問(wèn)應(yīng)用程序塊簡(jiǎn)化了實(shí)現(xiàn)常規(guī)數(shù)據(jù)訪問(wèn)功能的開發(fā)任務(wù)。應(yīng)用程序可以在各種場(chǎng)景中使用此應(yīng)用程序塊,例如為顯示而讀取數(shù)據(jù)、傳遞數(shù)據(jù)穿過(guò)應(yīng)用程序?qū)? application layers)、以及將修改的數(shù)據(jù)提交回?cái)?shù)據(jù)庫(kù)系統(tǒng)。應(yīng)用程序塊包含對(duì)存儲(chǔ)過(guò)程和內(nèi)聯(lián) SQL 的支持。常規(guī)內(nèi)部(housekeep)處理,如管理連接、創(chuàng)建并緩存參數(shù),都封裝在應(yīng)用程序塊的方法中。換句話說(shuō),數(shù)據(jù)訪問(wèn)應(yīng)用程序塊在簡(jiǎn)單易用的類中提供了對(duì) ADO.NET 的最常用的特性的訪問(wèn);這提高了開發(fā)人員的工作效率。
ADO.NET 2.0 提供了如 DbCommand 類和 DbConnection 這樣的類,這些類有助于從任何特定數(shù)據(jù)庫(kù)實(shí)現(xiàn)中抽象出數(shù)據(jù)提供程序。數(shù)據(jù)訪問(wèn)應(yīng)用程序塊利用了這些類,并且提供了加強(qiáng)支持?jǐn)?shù)據(jù)庫(kù)特定特性封裝的模型,例如參數(shù)發(fā)現(xiàn)和類型轉(zhuǎn)換。因此,應(yīng)用程序可以在不修改客戶代碼的情況下從一個(gè)數(shù)據(jù)庫(kù)移植到另一個(gè)數(shù)據(jù)庫(kù)。數(shù)據(jù)訪問(wèn)應(yīng)用程序塊包括一個(gè)抽象基類,它定義了一個(gè)通用的接口,并提供了許多在 ADO.NET 2.0 中可用的數(shù)據(jù)訪問(wèn)方法所需要的實(shí)現(xiàn)。
應(yīng)用程序塊還包含了專用于 Microsfot SQL Server、Microsoft SQL Server CE、和 Oracel 的類。這些類完成對(duì)特定數(shù)據(jù)庫(kù)類型的操作。應(yīng)用程序的代碼只為一種數(shù)據(jù)庫(kù)而編寫,例如 SQL Server,可以看到有許多為另一種數(shù)據(jù)庫(kù)編寫的代碼是一樣的,例如 Oracle 。
數(shù)據(jù)訪問(wèn)應(yīng)用程序塊的另一個(gè)特性是,應(yīng)用程序代碼可以由一個(gè) ADO.NET 連接字符串的名字,如"Customer" 或者 "Inventory" ,而引向一個(gè)特定的數(shù)據(jù)。應(yīng)用程序代碼可以指定一個(gè)數(shù)據(jù)庫(kù)命名實(shí)例,并傳遞此參數(shù)到 DatabaseFactory.CreateDatabase 方法。每個(gè)命名數(shù)據(jù)庫(kù)都有連接字符串保存在配置文件中。通過(guò)修改配置文件中的設(shè)置,開發(fā)人員可以在不同的數(shù)據(jù)庫(kù)配置下使用應(yīng)用程序而不需要重新編譯代碼。
數(shù)據(jù)訪問(wèn)應(yīng)用程序塊提供了下列好處:

  • 使用了由 ADO.NET 2.0 提供的功能并與其一起使用,可以同時(shí)使用 ADO.NET 和應(yīng)用程序塊的功能。
  • 減少編寫重復(fù)代碼完成標(biāo)準(zhǔn)任務(wù)的需要。
  • 有助于維護(hù)一致的數(shù)據(jù)訪問(wèn)實(shí)踐,無(wú)論是在應(yīng)用程序內(nèi)部還是企業(yè)間。
  • 減少了變更數(shù)據(jù)庫(kù)類型的困難。
  • 將開發(fā)人員從學(xué)習(xí)用于不同數(shù)據(jù)庫(kù)的不同編程模型中解放出來(lái)。
  • 減少了在開發(fā)人員移植應(yīng)用程序到另一種數(shù)據(jù)庫(kù)時(shí)不得不編寫的代碼的數(shù)量。

普通場(chǎng)景
開發(fā)人員經(jīng)常編寫使用數(shù)據(jù)庫(kù)的應(yīng)用程序。因?yàn)樗毡榱?#xff0c;開發(fā)人員可能會(huì)發(fā)現(xiàn)他們?yōu)槊總€(gè)應(yīng)用程序在重復(fù)編寫同樣的代碼。另外,這些應(yīng)用程序可能需要與不同的數(shù)據(jù)庫(kù)一起工作。盡管任務(wù)是相同的,代碼也必須適配以適應(yīng)每個(gè)數(shù)據(jù)庫(kù)的編程模型。數(shù)據(jù)訪問(wèn)應(yīng)用程序塊通過(guò)提供完成最常用的數(shù)據(jù)訪問(wèn)任務(wù)的邏輯來(lái)解決這些問(wèn)題。開發(fā)人員僅需要做如下事情:

  • 創(chuàng)建一個(gè) database 對(duì)象。
  • 提供用于命令的參數(shù),如果需要的話。
  • 調(diào)用適當(dāng)?shù)姆椒?#xff0c;這些方法已經(jīng)過(guò)性能優(yōu)化,并且是可移植的。


數(shù)據(jù)訪問(wèn)應(yīng)用程序塊可以透明的與 SQL Server、SQL Server CE、和 Oracle 數(shù)據(jù)庫(kù)一起工作。數(shù)據(jù)訪問(wèn)應(yīng)用程序塊為解決開發(fā)人員在編寫數(shù)據(jù)庫(kù)應(yīng)用程序時(shí)所面對(duì)的絕大多數(shù)普通任務(wù)而設(shè)計(jì)。這些任務(wù)根據(jù)場(chǎng)景進(jìn)行了組織。每個(gè)場(chǎng)景都人出了一個(gè)真實(shí)世界條件下的示例,例如從分類中獲取信息或者未完成銀行事務(wù),描述了條件所要求的數(shù)據(jù)庫(kù)功能,并展示完成任務(wù)的代碼。
根據(jù)場(chǎng)景組織這些任務(wù)的目的是給代碼一些上下文,來(lái)替代展示一組孤立的方法,而沒有它們最好使用在哪兒的意義,場(chǎng)景為代碼提供了一種設(shè)置,將它放置在其應(yīng)用程序必須訪問(wèn)數(shù)據(jù)庫(kù)的許多開發(fā)人員所熟悉的條件中。
場(chǎng)景如下:

  • 使用 DataReader 獲取多行數(shù)據(jù)
  • 使用 DataSet 獲取多行數(shù)據(jù)
  • 運(yùn)行一個(gè)命令并獲取輸出參數(shù)
  • 運(yùn)行一個(gè)命令并獲取單值項(xiàng)
  • 在一個(gè)事務(wù)中執(zhí)行多個(gè)操作
  • 從 SQL Server 中獲取 XML 數(shù)據(jù)
  • 使用包含在 DataSet 對(duì)象中的數(shù)據(jù)更新數(shù)據(jù)庫(kù)

示例應(yīng)用程序代碼
下列代碼展示了如何調(diào)用一個(gè)存儲(chǔ)過(guò)程并返回一個(gè) DataSet

Database db = DatabaseFactory.CreateDatabase(); 
?
DbCommand dbCommand = db.GetStoredProcCommand("GetProductsByCategory"); 
?
// Retrieve products from category 7.
db.AddInParameter(dbCommand, "CategoryID", DbType.Int32, 7); 
?
DataSet productDataSet = db.ExecuteDataSet(dbCommand); 

從3.1版本之后修改的特性

一般情況下,使用數(shù)據(jù)訪問(wèn)應(yīng)用程序塊的早期版本發(fā)布構(gòu)建的應(yīng)用程序不需要修改任何代碼就能使用 May 2008 發(fā)行的功能。可能需要更新引用以指向新的程序集,并更新配置文件以引用正確的應(yīng)用程序版本。然而在version 3.1 (May 2007)所做的一些修改會(huì)影響到你從早期版本遷移到現(xiàn)在的版.下面描述這些改變:

.NET Framework 2.0 TransactionScope 類

已經(jīng)修改某些 Database 類的方法以使用 .NET Framework 2.0 的 TransactionScope 類。這些方法,例如 ExecuteNonQuery ,已通過(guò)用 GetOpenConnection 方法替換掉 GetConnection 方法來(lái)修改為識(shí)別 TransactionScop 實(shí)例的有效時(shí)機(jī)。如果編寫了一個(gè)繼承自 Database 類的類,將需要考慮這些變化來(lái)重寫代碼。如果繼續(xù)使用 GetConnection 方法,將會(huì)收到一個(gè)編譯錯(cuò)誤。
另外,如果應(yīng)用程序使用了 ExecuteXmlReader 方法,可能需要重寫代碼以測(cè)試查看在關(guān)閉連接前 TransactionScope 實(shí)例是否是有效的。

SQL Server Compact Edition

Enterprise Library 3.1 – May 2007 和之后版本支持 SQL Server Compact Edition (CE)。SQL Server CE 提供了精減的關(guān)系數(shù)據(jù)庫(kù)的特性,以用于桌面和移動(dòng)應(yīng)用程序,這些程序需要本地?cái)?shù)據(jù)庫(kù)存儲(chǔ)但又不需要完整的 SQL Server 的功能。

何時(shí)使用數(shù)據(jù)訪問(wèn)應(yīng)用程序塊

?

數(shù)據(jù)訪問(wèn)應(yīng)用程序塊包含少量簡(jiǎn)化絕大多數(shù)訪問(wèn)數(shù)據(jù)庫(kù)的普通方法的方法。每個(gè)方法都封裝了獲取數(shù)據(jù)所需要的邏輯以及管理數(shù)據(jù)庫(kù)連接。如果應(yīng)用程序中使用標(biāo)準(zhǔn)的數(shù)據(jù)訪問(wèn)技術(shù)就可以考慮使用應(yīng)用程序塊。
應(yīng)用程序塊補(bǔ)充了 ADO.NET 2.0 中的代碼,以讓你在不同的數(shù)據(jù)庫(kù)類型中使用同樣的代碼。它包含了用于 SQL Server 和 Oracle 數(shù)據(jù)庫(kù)的類。這些類包含了提供特定數(shù)據(jù)庫(kù)特性如參數(shù)處理和游標(biāo)的實(shí)現(xiàn)的代碼。另外,GenericDatabase 類允許使用應(yīng)用程序塊與任何配置的 ADO.NET 2.0 DbProviderFactory 對(duì)象一起使用。可以通過(guò)添加新的惟數(shù)據(jù)庫(kù)特定特性或者提供已有數(shù)據(jù)庫(kù)自定義實(shí)現(xiàn)的數(shù)據(jù)庫(kù)類型來(lái)擴(kuò)展應(yīng)用程序塊。僅僅需要在在一個(gè)用于目標(biāo)數(shù)據(jù)庫(kù)的 ADO.NET 2.0 DbProviderFactory 類。

何時(shí)直接使用 ADO.NET


數(shù)據(jù)訪問(wèn)應(yīng)用程序塊是 ADO.NET 的一個(gè)補(bǔ)充;而不是替換。應(yīng)用程序塊提供了簡(jiǎn)化和方便,同時(shí)幫助開發(fā)人員以最佳實(shí)踐使用 ADO.NET 。如果應(yīng)用程序需要以特殊的方法獲取數(shù)據(jù),或者代碼需要定制以利用特定于特定數(shù)據(jù)庫(kù)的特性,使用 ADO.NET 可能更適合。

使用數(shù)據(jù)訪問(wèn)應(yīng)用程序塊開發(fā)應(yīng)用程序

首先解釋了如何配置應(yīng)用程序塊并將它添加到應(yīng)用程序中。然后,在關(guān)鍵場(chǎng)景中,解釋了如何在特定場(chǎng)景中使用應(yīng)用程序塊,例如獲取單個(gè)項(xiàng)或者使用 DataSet 對(duì)象獲取多行。最后,在開發(fā)任何細(xì)節(jié)中,給出了關(guān)于如連接管理、參數(shù)處理和處理異常等方面的更多信息。本主題假設(shè)使用的是原始的應(yīng)用程序塊,即沒有擴(kuò)展的。要學(xué)習(xí)如何添加功能,請(qǐng)參見擴(kuò)展和修改數(shù)據(jù)訪問(wèn)應(yīng)用程序塊。

輸入配置信息

下面這些過(guò)程展示了如何配置數(shù)據(jù)訪問(wèn)應(yīng)用程序塊。
此過(guò)程解釋了如何配置數(shù)據(jù)訪問(wèn)應(yīng)用程序塊。與節(jié)點(diǎn)關(guān)聯(lián)的屬性顯示在右邊的面板里。
添加數(shù)據(jù)訪問(wèn)應(yīng)用程序塊

  1. 打開配置文件。更多信息,請(qǐng)參數(shù)配置應(yīng)用程序塊。
  2. 右單擊Application Configuration,指向 New ,然后單擊 Data Access Application Block


下一過(guò)程解釋了如何配置默認(rèn)的數(shù)據(jù)庫(kù)實(shí)例,此實(shí)例在應(yīng)用程序調(diào)用不指定實(shí)例名稱的 DatabaseFactory.CreateDatabase 方法時(shí)使用。
配置默認(rèn)數(shù)據(jù)庫(kù)

  1. 在右面板中,展開 DefaultDatabase 屬性。
  2. DefaultDatabase 屬性輸入連接字符串的名稱或者從下拉列表中選擇它。默認(rèn)的連接字符串名稱是 ConnectionString 。
  3. (可選的)輸入一個(gè)新的名稱來(lái)設(shè)計(jì) Name 屬性,默認(rèn)名稱是 ConnectionString
  4. ProviderName 屬性節(jié),如果愿意,可能修改提供程序的名稱。輸入提供程序的名稱或者從下拉列表中選擇它。提供程序的默認(rèn)名稱是 System.Data.SqlClientProviderName 屬性必須是一個(gè)在 DBProviderFactory 類中指定的提供程序的名稱。


下一過(guò)程解釋了如何為命名數(shù)據(jù)庫(kù)實(shí)例創(chuàng)建連接字符串。當(dāng)配置控制臺(tái)保存連接字符串時(shí),它生成了一個(gè)以 name = value 格式保存值對(duì)的以分號(hào)分割的字符串。例如,如果使用配置控制臺(tái)來(lái)用默認(rèn)值生成連接字符串,配置控制臺(tái)臺(tái)將生成下列連接字符串。

Database=Database;Server=(local)\SQLEXPRESS;Integrated Security=SSPI;


配置連接字符串

  1. 單擊 ConnectionString 節(jié)點(diǎn)。
  2. (可選的)輸入一個(gè)新的名稱以設(shè)置 Name 屬性,這是 ConnectionString 節(jié)點(diǎn)的名稱。默認(rèn)的名稱是 ConnectionString
  3. (可選的)在 ProviderName 屬性節(jié),修改提供程序的名稱。輸入提供程序的名稱或者從下拉列表中選擇它。默認(rèn)的提供程序的名稱是 System.Data.SqlClientProviderName 屬性必須是一個(gè)指定在 DbProviderFactory 類中的提供程序的名稱。
  4. 用下列值更新 ConnectionString 屬性。例如:
Database=Database;Server=(local)\SQLEXPRESS;Integrated Security=SSPI


下一過(guò)程展示了如何配置一個(gè) SQL Server CE 數(shù)據(jù)庫(kù)。如果應(yīng)用程序總是使用在配置期間命名的單一文件,這些步驟是合適的。關(guān)于 SQL Server CE 的更多信息,請(qǐng)參見創(chuàng)建數(shù)據(jù)庫(kù)對(duì)象的細(xì)節(jié)。
配置 SQL Server CE

  1. 右單擊 Custom Provider Mappings,指向 New ,然后單擊 Provider Mapping
  2. 屬性面板中單擊Nmae,在下拉框中選擇Microsoft.SqlServerCe.Client
  3. 屬性面板中單擊 TypeName 屬性。單擊省略號(hào)(...)按鈕
  4. Type Selector 中,找到并雙擊 SqlCeDatabase
  5. ConnectionStrings 節(jié)點(diǎn)上右單擊并單擊 New ,然后單擊 Connection String
  6. (可選的)輸入新的名稱以設(shè)置 Name 屬性。這是 ConnectionString 節(jié)點(diǎn)的名稱。默認(rèn)的名稱是 ConnectionString
  7. ProviderName 屬性節(jié),修改提供程序的名稱為 Microsoft.SqlServerCe.Client
  8. ConnectionString 屬性節(jié),輸入理想的 SQL Server CE 連接字符串,例如:
Data Source='C:\MyApp\MyDatabase.sdf'


下一過(guò)程展示了如果添加 Oracle 包。Oracel 包服務(wù)是分組存儲(chǔ)過(guò)程到普通組的一種方式,通常基于它們的功能。當(dāng)應(yīng)用程序調(diào)用在包中的 Oracle 存儲(chǔ)過(guò)程時(shí),代碼必須用包名做為存儲(chǔ)過(guò)程的前綴。例如,要調(diào)用在命名為 Employee_pkg 的包中的名為 GetEmployeeName 的過(guò)程,將調(diào)用 Employee_pkg.GetEmployeeName
將這段代碼加入到應(yīng)用程序中將降低可移植性,因?yàn)檎Z(yǔ)法專用于 Oracle 。另一種替換做法是,數(shù)據(jù)訪問(wèn)應(yīng)用程序塊會(huì)用包名做為存儲(chǔ)過(guò)程的前綴。這意味著客戶端代碼在調(diào)用存儲(chǔ)過(guò)程時(shí)不需要指定包名。要做到這一點(diǎn),應(yīng)用程序塊使用在配置文件中的信息。OraclePackage 節(jié)點(diǎn)保存了一個(gè)名稱/前綴對(duì)。名稱是包的名稱,前綴是一個(gè)與包相關(guān)的字符串。所有以指定的前綴開始的存儲(chǔ)過(guò)程都假定在相關(guān)的包內(nèi)。
當(dāng)應(yīng)用程序調(diào)用一個(gè)存儲(chǔ)過(guò)程時(shí),數(shù)據(jù)訪問(wèn)應(yīng)用程序塊檢查看是否以配置文件中的某個(gè)前綴開始。如果是,應(yīng)用程序塊為存儲(chǔ)過(guò)程加上相應(yīng)的包名前綴。(應(yīng)用程序塊將使用找到的第一個(gè)匹配)。如果指定一個(gè)星號(hào)(*)為前綴,關(guān)聯(lián)包將用于所有存儲(chǔ)過(guò)程。
配置 Oracle 包

  1. 右單擊 ConnectionString ,指向 New ,然后單擊 OraclePackages
  2. 單擊 OraclePackage
  3. 輸入 Oracle 包的名稱以修改 Name 屬性。默認(rèn)為 OraclePackage
  4. 輸入 Prefix 屬性的值。

下一過(guò)程解釋了如何通過(guò)關(guān)聯(lián)提供程序和數(shù)據(jù)庫(kù)全名稱來(lái)添加自定義的提供程序映射。
配置自定義的提供程序

  1. 右單擊 CustomProviderMappings 節(jié)點(diǎn),指向 New ,然后單擊 ProviderMapping
  2. (可選的)輸入新的名稱以設(shè)置 Name 屬性。輸入提供程序的名稱或從下拉列表中選擇。默認(rèn)的提供程序是 System.Data.SqlClientProviderName 屬性必須是一個(gè)在 DbProviderFactory 類中指定的提供程序名稱。
  3. TypeName 屬性節(jié)中。單擊省略號(hào)按鈕(...)并使用'Type Selector 選擇 Enterprise Library 數(shù)據(jù)庫(kù)類型的全名稱。

可以手工編輯 XML 數(shù)據(jù),但 Enterprise Library 極大的簡(jiǎn)化了此任務(wù)。如果選擇手工編輯 XML ,則要使用包含在本主題中的模式信息。
配置文件有如下的節(jié)處理程序聲明:

<configSections><section name="dataConfiguration"type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings,Microsoft.Practices.EnterpriseLibrary.Data, Version=4.0.0.0,Culture=neutral, PublicKeyToken=31bf3856ad364e35" /><section name="oracleConnectionSettings" type="Microsoft.Practices.EnterpriseLibrary.Data.Oracle.Configuration.OracleConnectionSettings,Microsoft.Practices.EnterpriseLibrary.Data, Version=4.0.0.0,Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>

節(jié)處理程序聲明包括配置設(shè)置節(jié)的名稱和處理節(jié)中配置數(shù)據(jù)的節(jié)處理程序的類名。第一個(gè)配置設(shè)計(jì)節(jié)的名稱為 dataConfiguration ,節(jié)處理程序的類名為 DatabaseSettings (在 Microsoft.Practices.EnterpriseLibrary.Data.Configuration 命名空間中)。
第二個(gè)配置設(shè)置節(jié)是 oracleConnectionSettings 。節(jié)處理程序類的名稱為 OracleConnectionSettings (在 Microsoft.Practices.EnterpriseLibrary.Data.Oracle.Configuration 命名空間中 )。
connectionStrings 元素
connectionStrings 元素列出了可被應(yīng)用程序使用的數(shù)據(jù)庫(kù)連接,此元素不是必須的。
屬性和子元素
下面的節(jié)描述了 connectionStrings 元素的屬性和子元素。
add 子元素
add 元素是 connectionStrings 元素的子元素。add 元素添加一個(gè)數(shù)據(jù)庫(kù)連接,此元素不是必須的,可以有多個(gè) add 元素。

providerMappings 子元素
這是一個(gè) dataConfiguration 元素的子元素,只有在通過(guò)派生自 ADO.NET 的 Database 類而不是 GenericDatabase 類的提供程序時(shí)才需要指定提供程序的映射。SQL Server 和 Oracle 數(shù)據(jù)庫(kù)默認(rèn)已配置,所以不需要再在此節(jié)中指定。指定在此節(jié)中的一個(gè)數(shù)據(jù)庫(kù)示例是 SQL Server CE 。
add 子元素
addproviderMappings 元素的子元素。add 元素添加一個(gè)數(shù)據(jù)庫(kù)連接。此元素不是必須的,可以有多個(gè) add 元素。

表3 列出了素的屬性

packages 子元素
這是 add 元素的一個(gè)子元素,指定一個(gè) Oracle 的包。此元素是必須的。
add 子元素
這是 packages 元素的一個(gè)子元素。 add 元素添加一個(gè) Oracle 的包。此元素不是必須的。可以有多個(gè) add 元素。
屬性
表 5 列出了 add 子元素的屬性。

添加應(yīng)用程序代碼

數(shù)據(jù)訪問(wèn)應(yīng)用程序塊為支持絕大多數(shù)訪問(wèn)數(shù)據(jù)庫(kù)場(chǎng)景而設(shè)計(jì)。在添加自己的應(yīng)用程序代碼時(shí),請(qǐng)參考在關(guān)鍵場(chǎng)景節(jié)中的場(chǎng)景,然后選擇一種與自己的情況最匹配的方法。使用場(chǎng)景中的代碼,或者如果需要,修改它以適合自己的需要。
首先,必須準(zhǔn)備自己的應(yīng)用程序以使用數(shù)據(jù)訪問(wèn)應(yīng)用程序塊。
準(zhǔn)備應(yīng)用程序

  1. 添加到數(shù)據(jù)訪問(wèn)應(yīng)用程序塊程序集的引用。在 Visual Studio 中,在解決方案管理器中右單擊項(xiàng)目節(jié)點(diǎn),然后單擊添加引用。單擊瀏覽標(biāo)簽,然后導(dǎo)航到 Microsoft.Practices.EnterpriseLibrary.Data.dll 的位置。選擇程序集,然后單擊確定以添加引用。
  2. 按同樣的步驟,添加到 Enterprise Library 內(nèi)核程序集 Microsoft.Practices.EnterpriseLibrary.Common.dllMicrosoft.Practices.ObjectBuilde2r.dll 的引用。
  3. (可選的) 要不帶完整的精確的元素引用使用來(lái)自加密應(yīng)用程序塊的元素,可以添加下列的 using 語(yǔ)句(C#)或者 Imports 語(yǔ)句(Visual Basic)到源代碼文件的頂部。
using Microsoft.Practices.EnterpriseLibrary.Data;
using System.Data;

創(chuàng)建 Database 對(duì)象
所有數(shù)據(jù)訪問(wèn)方法都相對(duì)于 Database 的對(duì)象。可以使用 DatabaseFactory 來(lái)創(chuàng)建 Database 對(duì)象。由工廠生成的 Database 對(duì)象的特定類型是由應(yīng)用程序的配置信息決定的。
可以使用配置控制臺(tái)指定一個(gè)默認(rèn)的數(shù)據(jù)庫(kù)實(shí)例。在不傳遞數(shù)據(jù)庫(kù)實(shí)例名調(diào)用 CreateDatabase 方法時(shí),DatabaseFactory 創(chuàng)建由默認(rèn)實(shí)例指定的 database 。下列應(yīng)用程序代碼展示了如何創(chuàng)建一個(gè)默認(rèn)實(shí)例的 Database 對(duì)象。

Database db = DatabaseFactory.CreateDatabase();

另一種方法是,應(yīng)用程序代碼可以指定一個(gè)命名的數(shù)據(jù)庫(kù)實(shí)例。例如,如果使用配置控制臺(tái)創(chuàng)建了名為 "Sales" 的實(shí)例,則為特定實(shí)例創(chuàng)建 Database 對(duì)象的代碼可能如下。

Database db = DatabaseFactory.CreateDatabase("Sales");

如果要?jiǎng)?chuàng)建的數(shù)據(jù)庫(kù)的連接字符串是已知的,也要以放棄應(yīng)用程序的配置信息,而是使用構(gòu)造函數(shù)直接創(chuàng)建 Database 對(duì)象。因?yàn)?Database 類是一個(gè)抽象基類,所以必須構(gòu)建一個(gè)它的派生類型。派生的 Database 類型決定了 ADO.NET 數(shù)據(jù)提供程序。例如,SqlDatabase 類使用 SqlClientFactory 提供程序,SqlCeDatabase 使用 SqlCeProviderFactory 提供程序,以及 OracleDatabase 使用 OracleClientFactory 提供程序。為連接字符串構(gòu)建正確類型的 Database 類是你的責(zé)任。
下列代碼使用提供的連接字符串創(chuàng)建了一個(gè) SqlDatabase 對(duì)象。

// Assume the method GetConnectionString exists in your application and 
// returns a valid connection string.
string myConnectionString = GetConnectionString();SqlDatabase sqlDatabase = new SqlDatabase(myConnectionString);

如果通過(guò)不是 ADO.NET SQL 數(shù)據(jù)提供程序或者 Oracle 數(shù)據(jù)提供程序的數(shù)據(jù)提供程序使用一個(gè)連接字符串,可以創(chuàng)建一個(gè) GenericDatabase 對(duì)象。在創(chuàng)建 GenericDatabase 對(duì)象時(shí),必須支持 DbProviderFactory 對(duì)象。
選擇適當(dāng)?shù)闹剌d方法
每個(gè)數(shù)據(jù)訪問(wèn)方法都有多個(gè)重載。下列描述和指南可以幫助你選擇合適的重載:

  • 有可以接受 ADO.NET DbCommand 對(duì)象的重載。這些重載為每個(gè)方法提供了最大的靈活性和控制。
  • 有接受存儲(chǔ)過(guò)程名稱和用于存儲(chǔ)過(guò)程參數(shù)值的值集合的重載。這些重載在應(yīng)用程序調(diào)用僅有輸入?yún)?shù)的存儲(chǔ)過(guò)程時(shí)比較方便。
  • 有接受 System.Data.CommandType 和表示命令的字符串的重載。這些方便的重載在應(yīng)用程序執(zhí)行不帶參數(shù)的內(nèi)聯(lián) SQL 語(yǔ)句或存儲(chǔ)過(guò)程時(shí)使用。
  • 最后,以上每個(gè)重載都包含一個(gè)接受一個(gè)事務(wù)的重載。這允許在一個(gè)已存在的事務(wù)中執(zhí)行方法時(shí)使用需要的重載類型。


每個(gè)關(guān)鍵場(chǎng)景示范了特定方法可用重載之一,許多場(chǎng)景都可以使用其他可用的重載完成。

創(chuàng)建 Database 對(duì)象的細(xì)節(jié)

可以使用工廠創(chuàng)建一個(gè) Database 對(duì)象或者直接構(gòu)建一個(gè)。工廠使用配置信息決定連接字符串、ADO.NET 數(shù)據(jù)提供程序和要構(gòu)建的適當(dāng)?shù)呐缮詳?shù)據(jù)訪問(wèn)應(yīng)用程序塊 Database 的對(duì)象。另一種時(shí),傳遞所有需要的信息給對(duì)象的構(gòu)造函數(shù)直接創(chuàng)建 Database 對(duì)象。
在要使用由 Enterprise Library 支持的保存在某個(gè)位置的配置信息時(shí)或者使用由 ADO.NET 管理的連接字符串時(shí)使用工廠。例如,使用工廠用保存在應(yīng)用程序配置文件中的 <connectionStrings> 節(jié)中的連接字符串信息創(chuàng)建 Database 對(duì)象。也可以使用工廠用保存在另一個(gè)配置源中的連接字符串構(gòu)建一個(gè) Database 對(duì)象。必須使用另一個(gè)默認(rèn)配置源來(lái)配置應(yīng)用程序,以允許工廠用保存在那個(gè)配置源中的連接字符串創(chuàng)建對(duì)象。在從不是默認(rèn)配置源中的某些源中獲取連接字符串時(shí),可以使用構(gòu)建函數(shù)。
CreateDatabase 方法是 DatabaseFactory 類的一個(gè)靜態(tài)方法。工廠基于配置文件中的信息創(chuàng)建一個(gè)正確的 database 類,并返回基類的子類的對(duì)象:Database 到客戶代碼。除非需要特定于特殊數(shù)據(jù)庫(kù)類型的命令,例如 SQL Server ,否則應(yīng)該僅使用 Database 基類的的可用方法以保持應(yīng)用程序所使用的數(shù)據(jù)庫(kù)是不可知的。特定的數(shù)據(jù)庫(kù)派生類型的創(chuàng)建對(duì)應(yīng)用程序代碼而言是透明的,因此,同樣可以不需要考慮所使用的數(shù)據(jù)庫(kù)類型。
可以使用 CreateDatabase 方法來(lái)基于默認(rèn)配置指定創(chuàng)建的數(shù)據(jù)庫(kù)類型。通過(guò)修改默認(rèn)配置,可以使未經(jīng)修改的應(yīng)用程序運(yùn)行于不同的數(shù)據(jù)庫(kù)。
也可以使用命名的數(shù)據(jù)庫(kù)實(shí)例,例如在應(yīng)用程序中的 "Customers" 。工廠使用配置文件中的連接字符串來(lái)查找與特定命名實(shí)例相關(guān)的信息以創(chuàng)建正確的數(shù)據(jù)庫(kù)類型。
如果需要使用某個(gè)或另一個(gè)數(shù)據(jù)庫(kù)特定的命令,就必須通過(guò)向下類型轉(zhuǎn)換(downcasting)指定期望由工廠創(chuàng)建的數(shù)據(jù)庫(kù)類型。
最后,可以忽略應(yīng)用程序的配置信息直接創(chuàng)建一個(gè) DataBase 對(duì)象子類型的 Database 對(duì)象。要做到這一點(diǎn),必須知道要?jiǎng)?chuàng)建的數(shù)據(jù)庫(kù)的類型,以及連接字符串和其他任何子類型需要的信息。
創(chuàng)建默認(rèn)數(shù)據(jù)庫(kù)
不指定參數(shù)的調(diào)用工廠的 CreateDatabase 方法將創(chuàng)建一個(gè)默認(rèn)的 database 。配置文件決定哪個(gè)命名實(shí)例是默認(rèn)實(shí)例。可以使用配置控制臺(tái)修改默認(rèn)實(shí)例。
下列代碼展示了如何創(chuàng)建一個(gè)標(biāo)記為默認(rèn)實(shí)例的 database 對(duì)象。

Database dbSvc = DatabaseFactory.CreateDatabase();

注意
如果配置文件沒有指定默認(rèn)實(shí)例,并且客戶代碼在調(diào)用 CreateDatabase 方法時(shí)也沒有指定參數(shù),應(yīng)用程序塊將拋出異常。

使用實(shí)例
要使用實(shí)例,可以通過(guò)邏輯名稱在應(yīng)用程序代碼中引用 database ,并且修改數(shù)據(jù)庫(kù)配置信息(如位置或連接字符串信息)而不用重新編譯代碼。
下列示例展示了如何使用名稱“Sales”創(chuàng)建 database 。

// Use a named database instance that refers to an arbitrary database type,
// which is determined by configuration information.
Database myDb = DatabaseFactory.CreateDatabase("Sales");
創(chuàng)建特定的 Database 類型
如果必須使用專用于特定數(shù)據(jù)庫(kù)類型的方法,在創(chuàng)建數(shù)據(jù)庫(kù)時(shí)可以指定 database 類型。下列代碼要求工廠創(chuàng)建一個(gè) SqlDatabase 對(duì)象。

// Create a SQL database.
SqlDatabase dbSQL = DatabaseFactory.CreateDatabase("Sales") as SqlDatabase;

同樣,要?jiǎng)?chuàng)建一個(gè) Oracle 數(shù)據(jù)庫(kù),使用 OracleDatabase 。要?jiǎng)?chuàng)建一個(gè) SQL CE 數(shù)據(jù)庫(kù),使用 SqlCeDatabase 類型。
不使用配置創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)
可以通過(guò)提供一個(gè)連接字符串給 database 類構(gòu)造函數(shù)來(lái)不使用配置數(shù)據(jù)的創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)對(duì)象。下列代碼展示了如何創(chuàng)建一個(gè) SqlDatabase 對(duì)象。

// Assume your application contains the routine GetConnectionString.
string myConnectionString = GetConnectionString();
SqlDatabase sqlDatabase = new SqlDatabase(myConnectionString);

下列代碼展示了如何創(chuàng)建一個(gè) GenericDatabase 對(duì)象。必須提供連接字符串和 DbProviderFactory 對(duì)象。在這種情況下,DbProviderFactory 對(duì)象是 OdbcFactory 。

GenericDatabase db = new GenericDatabase(connectionString, OdbcFactory.Instance);

使用 SQL Server CE
SQL Server CE 是一個(gè)小型的、進(jìn)程內(nèi)的數(shù)據(jù)庫(kù),它提供了關(guān)系數(shù)據(jù)庫(kù)的必須功能,目的在于需要本地?cái)?shù)據(jù)存儲(chǔ)但不需要 SQL Server 的完整功能的桌面和移動(dòng)應(yīng)用程序。每個(gè)數(shù)據(jù)庫(kù)都保存在一個(gè)文件中,默認(rèn)情況下,擴(kuò)展名為 .sdf 。使用 CreateFile 方法可以創(chuàng)建一個(gè)新的空數(shù)據(jù)庫(kù),此方法使用來(lái)自連接串的文件名。
對(duì)于 SQL Server CE ,打開一個(gè)連接就是打開數(shù)據(jù)庫(kù)文件。結(jié)果是,為每個(gè)請(qǐng)求創(chuàng)建和釋放連接將非常緩慢。為了避免這些性能問(wèn)題,使用 SQL Server CE 的應(yīng)用程序通常在使用數(shù)據(jù)庫(kù)期間盡可能長(zhǎng)的保存連接打開。
在第一次調(diào)用 Database 類的方法時(shí),提供程序創(chuàng)建一個(gè)附加的 “keep alive”連接,它在內(nèi)存中保持了數(shù)據(jù)庫(kù)引擎。應(yīng)用程序?yàn)槊總€(gè) Database 類方法的調(diào)用打開和關(guān)閉其他的連接,但關(guān)閉這些連接不會(huì)關(guān)閉 “keep alive”連接。
要打開一個(gè)數(shù)據(jù)庫(kù),使用 CreateConnection 方法打開到它的連接。這個(gè)方法創(chuàng)建了 “keep alive”連接。當(dāng)使用完數(shù)據(jù)庫(kù)后,必須使用 CloseSharedConnection 方法關(guān)閉到數(shù)據(jù)庫(kù)的 “keep alive”連接。對(duì)于每個(gè)連接字符串僅有一個(gè) “keep alive”連接,盡管對(duì)于同樣的連接字符串可以有多個(gè)打開的連接。
因?yàn)?SQL Server CE 是一個(gè)進(jìn)程內(nèi)的數(shù)據(jù)庫(kù),對(duì)數(shù)據(jù)庫(kù)的多個(gè)調(diào)用將是快而有效的。SQL Server CE 不支持存儲(chǔ)過(guò)程。如果試圖使用任何 Execute 方法,如 ExecuteScalarExecuteNonQuery ,以一個(gè)存儲(chǔ)過(guò)程做為參數(shù)的話,應(yīng)用程序塊將拋出異常。不用存儲(chǔ)過(guò)程,可以使用內(nèi)聯(lián)的 SQL 語(yǔ)句來(lái)代替。在此有些 Execute 方法的重載是接受一個(gè) SQL 語(yǔ)句為參數(shù)的。因?yàn)榇鎯?chǔ)過(guò)程不受支持的同樣原因,只能在一個(gè)請(qǐng)求中發(fā)送一條 SQL 語(yǔ)句。
SQL Server CE 有一個(gè)名為 SqlCeResultSet 的特殊結(jié)果集。這是查詢返回的結(jié)果集類型。它支持在數(shù)據(jù)庫(kù)中的查詢、前向和后向移動(dòng)、以及修改數(shù)據(jù)。
關(guān)于 SQL Server CE 的一般信息,請(qǐng)參見 Microsoft Web 站點(diǎn)上的 Microsoft SQL Server: SQL Server 2005 Compact Edition 。相關(guān) API 的信息,請(qǐng)參見 MSDN 上的 System.Data.SqlServerCe 命名空間頁(yè)。

注意 SQL Server CE 僅在完全信任環(huán)境中操作。

通過(guò) TransactionScope 類使用 Oracle
盡管可以通過(guò) Oracle 客戶端來(lái)使用 TransactionScope 類,但事務(wù)總是被處理為分布式事務(wù)而不是輕量級(jí)的事務(wù)。分布式事務(wù)有較高的性能開銷。
.NET Framework 托管的用于 Oracle 的提供程序需要一個(gè)名為 oramts.dll 的文件以使用 TransactionScope 類。更多信息,請(qǐng)參見 Microsoft 幫助和支持 Web 站點(diǎn)。
如果通過(guò) Microsoft 事務(wù)服務(wù)器使用 Oracle,請(qǐng)參見 Oracle Web 站點(diǎn)上的 Oracle Services for MTS以獲得適當(dāng)?shù)南螺d。
使用提示
DatabaseFactory 對(duì)象基于 ADO.NET 的 DbProviderFactory 對(duì)象決定哪種 Database 對(duì)象被創(chuàng)建,DbProviderFactory 與連接字符串相關(guān)聯(lián)。連接字符串保存在配置文件的 <connectionStrings> 節(jié)中。默認(rèn)情況下,應(yīng)用程序塊為 System.Data.SqlClient 類型的數(shù)據(jù)提供程序創(chuàng)建 SqlDatabase 類型的 Database 對(duì)象,為 System.Data.SqlServerCe 類型的數(shù)據(jù)提供程序創(chuàng)建 SqlCeDatabase 類型的對(duì)象,為 System.Data.OracleClient 類型的數(shù)據(jù)提供程序創(chuàng)建 OracleDatabase 類型的對(duì)象,為其他所有數(shù)據(jù)提供程序類型創(chuàng)建 GenericDatabase 類型的對(duì)象。
GenericDatabase 類僅支持由 ADO.NET 提供功能的數(shù)據(jù)庫(kù)提供程序。特別的,支持參數(shù)發(fā)現(xiàn)的數(shù)據(jù)訪問(wèn)重載無(wú)法工作。GenericDatabase 可以由任何 .NET 托管的提供程序使用,包括 .NET Framework 2.0 中的 ODBC 和 OLE-DB 提供程序。可以通過(guò)在配置文件中的配置設(shè)置來(lái)覆蓋數(shù)據(jù)提供程序類型和 Database 對(duì)象類型之間的映射。更多信息,請(qǐng)參見數(shù)據(jù)訪問(wèn)應(yīng)用程序塊的設(shè)計(jì)。

創(chuàng)建 DbCommand 對(duì)象

數(shù)據(jù)訪問(wèn)應(yīng)用程序塊提供了獲取 ADO.NET DbCommand 對(duì)象的的統(tǒng)一方法。應(yīng)用程序塊的數(shù)據(jù)訪問(wèn)方法包含了接受 DbCommand 對(duì)象的重載。如果用 DbCommand 對(duì)象來(lái)使用重載,在調(diào)用存儲(chǔ)過(guò)程時(shí)將可以進(jìn)行更多的控制。例如,如果使用 DbCommand 對(duì)象,就可以使用在輸出參數(shù)中返回多個(gè)結(jié)果的存儲(chǔ)過(guò)程。另外,DbCommand 對(duì)象允許指定存儲(chǔ)過(guò)程的超時(shí)值。
創(chuàng)建 DbCommand 對(duì)象的方法分為二種類型:

  • 表示存儲(chǔ)過(guò)程調(diào)用的那些方法(例如,GetCustomers)
  • 表示 SQL 文本命令的那些方法(例如,Select CustomerID, Fullname From Customers )


調(diào)用的獲取 DbCommand 對(duì)象的方法由是要執(zhí)行內(nèi)聯(lián)的 SQL 還是調(diào)用存儲(chǔ)過(guò)程來(lái)決定。用于存儲(chǔ)過(guò)程的創(chuàng)建 DbCommand 對(duì)象的方法還提供參數(shù)緩存。關(guān)于參數(shù)緩存的更多信息,請(qǐng)參見處理參數(shù)。
所有 DbCommand 對(duì)象的創(chuàng)建都使用 Database 類的方法,這些方法如下:

  • GetStoredProcCommand。此方法用于存儲(chǔ)過(guò)程命令。
  • GetSqlStringCommand。此方法用于 SQL 文本命令。


二個(gè)方法都返回一個(gè) DbCommand 對(duì)象。

注意:SQL Server CE 不支持存儲(chǔ)過(guò)程,用內(nèi)聯(lián) SQL 語(yǔ)句來(lái)代替。更多信息,請(qǐng)參見創(chuàng)建 Database 對(duì)象的細(xì)節(jié)。

用于 SQL 語(yǔ)句的 DbCommand對(duì)象
使用 GetSqlStringCommand 方法創(chuàng)建用于內(nèi)聯(lián) SQL 語(yǔ)句的 DbCommand 對(duì)象。特定的 SQL 命令在方法調(diào)用時(shí)做為一個(gè)參數(shù)進(jìn)行傳遞。
下列代碼展示了如何使用 GetSqlStringCommand

Database db = DatabaseFactory.CreateDatabase();
string sqlCommand = "Select CustomerID, LastName, FirstName From Customers";
DbCommand dbCommand = db.GetSqlStringCommand(sqlCommand);

用于存儲(chǔ)過(guò)程的 DbCommand 對(duì)象
要執(zhí)行存儲(chǔ)過(guò)程,必須使用 GetStoredProcCommand 方法來(lái)創(chuàng)建 DbCommand 對(duì)象。要執(zhí)行存儲(chǔ)過(guò)程的名稱在方法調(diào)用時(shí)做為一個(gè)參數(shù)傳遞。
下列代碼展示了如何使用 GetStoredProcCommand

Database db = DatabaseFactory.CreateDatabase();DbCommand dbCommand = db.GetStoredProcCommand("GetProductsByCategory"); 

注意:存儲(chǔ)過(guò)程的參數(shù)受 Database 類的方法的支持。關(guān)于如何使用存儲(chǔ)過(guò)程參數(shù)參數(shù)的更多信息,請(qǐng)參見處理參數(shù)。

?

管理連接

數(shù)據(jù)庫(kù)連接是有限資源,它們的妥善管理對(duì)可擴(kuò)展的應(yīng)用程序來(lái)說(shuō)是必不可少的。僅在需要時(shí)保持連接打開并盡快關(guān)閉是一個(gè)很好的實(shí)踐。根據(jù)設(shè)計(jì),絕大多數(shù)的 Database 類方法在每次調(diào)用時(shí)打開和關(guān)閉到數(shù)據(jù)庫(kù)的連接。因?yàn)?#xff0c;應(yīng)用程序代碼不需要包含用于管理連接的代碼。(默認(rèn)情況下,基于性能的原因,ADO.NET 將連接返回到連接池中,而不是關(guān)閉他們。因此,不需要緩存 Database 對(duì)象。)
例如,ExecuteDataSet 返回包含所有數(shù)據(jù)的 DataSet 對(duì)象。這給了你一個(gè)自己的本地副本。對(duì) ExecuteDataSet 的調(diào)用打開了一個(gè)連接、組裝了一個(gè) DataSet、然后在返回結(jié)果前關(guān)閉連接。
下列代碼示范了 ExecuteDataSet 方法的使用。

Database db = DatabaseFactory.CreateDatabase();
string sqlCommand = "Select ProductID, ProductName From Products";
DbCommand dbCommand = db.GetSqlStringCommand(sqlCommand);
// No need to open the connection; just make the call.
DataSet customerDataSet = db.ExecuteDataSet(dbCommand);

然而,在關(guān)閉連接時(shí)有一些未清理的其他情況。一個(gè)例子就是 ExecuteReader 方法。此方法返回實(shí)現(xiàn) IDataReader 接口的對(duì)象。Database 基類有一個(gè)返回 DbDataReader 對(duì)象的默認(rèn)實(shí)現(xiàn)。DbDataReader 對(duì)象被設(shè)計(jì)用來(lái)讀取需要的數(shù)據(jù)的特定部分,它需要一個(gè)打開的連接。換句話說(shuō),它不知道應(yīng)用程序何時(shí)不再需要 DbDataReader 。如果數(shù)據(jù)訪問(wèn)應(yīng)用程序塊在返回 DbDataReader 之前就關(guān)閉了連接,DbDataReader 對(duì)客戶代碼而言是無(wú)用的。因此,DbDataReader 方法指定底層的 ADO.NET 在 DbDataReader 完成后自動(dòng)關(guān)閉連接。在這種情況下,它被認(rèn)為是由應(yīng)用程序確定 DbDataReader 及時(shí)關(guān)閉的最好方法,可以使用 DbDataReader.close 方法顯示的關(guān)閉 reader 或者強(qiáng)制 DbDataReader 的銷毀,這是 Close 方法被調(diào)用的結(jié)果。
下列代碼示范了對(duì) ExecuteReader 方法的調(diào)用。using 語(yǔ)句(在 Visual Basic 中為 Using )確保 DbDataReader 對(duì)象被銷毀,并在銷毀的過(guò)程中關(guān)閉 DbDataReader 對(duì)象。

Database db = DatabaseFactory.CreateDatabase();DbCommand dbCommand = db.GetSqlStringCommand("Select Name, Address From Customers");
using (IDataReader dataReader = db.ExecuteReader(dbCommand))
{
// Process results
} 
?
使用 TransactionScope 類

在此對(duì) Database 類的某些方法進(jìn)行了一些修改,以利用 .NET Framework 2.0 的 TransactionScope 類。此類自動(dòng)將數(shù)據(jù)庫(kù)調(diào)用加入到一個(gè)外圍的事務(wù)中。這在將業(yè)務(wù)對(duì)象加入到一個(gè)事務(wù)中而不傳遞事務(wù)到這些業(yè)務(wù)對(duì)象中時(shí)非常有用。以下是 TransactionScope 類的使用的基本模型。

using (TransactionScope scope = new
?????????? TransactionScope(TransactionScopeOption.RequiresNew))
{
??? int rows = db.ExecuteNonQuery(CommandType.Text, insertString);
??? rows = db.ExecuteNonQuery(CommandType.Text, insertString2);
}

二個(gè) ExecuteNonQuery 方法將行插入到了在創(chuàng)建 TransactionScope 實(shí)例時(shí)定義的事務(wù)中。
TransactionScope 類創(chuàng)建了一個(gè)本地的、輕量級(jí)的事務(wù)。它假定為發(fā)生在事務(wù)中的所有的數(shù)據(jù)庫(kù)調(diào)用使用一個(gè)連接。這意味著,做為傳遞 DbTransaction 實(shí)例的另一種方法,簡(jiǎn)單的傳遞連接,然后 .NET Framework 自動(dòng)為執(zhí)行的每個(gè)命令設(shè)置了連接。
Enterprise Library,換句話說(shuō),通常為每個(gè)請(qǐng)求打開并關(guān)閉連接。此方法與 TransactionScope 類工作的方法不兼容。如果有多個(gè)連接,TransactionScope 類將認(rèn)為事務(wù)是分布式事務(wù)。分布式事務(wù)比本地事務(wù)有顯著的性能和資源消耗。
要避免這些,Database 類的方法,如 ExecuteDataSet ,識(shí)別 TransactionScope 實(shí)例活動(dòng)的時(shí)機(jī),并添加 database 調(diào)用到此事務(wù)中。如果事務(wù)的當(dāng)前活動(dòng)是使用 TransactionScope 實(shí)例的結(jié)果,Database 類方法會(huì)使用單一的連接。
特別的,GetOpenConnection 方法替換了 Database 方法中的 OpenConnection 方法,GetOpenConnection 方法返回一個(gè)連接包裝器。如果沒有事務(wù)正在處理,方法將銷毀包裝器。然而,當(dāng)事務(wù)還在處理中時(shí),方法將保持連接打開。
如果使用 ExecuteXmlReader 方法,將測(cè)試看 TransactionScope 實(shí)例是否是活動(dòng)的。此方法將返回保持 reader 使用的連接的 XmlReader 對(duì)象。當(dāng) reader 使用結(jié)束后,最后的方法就是關(guān)閉此連接。然而,如果使用的是 TransactionScope 的實(shí)例,必須不能這么做,因?yàn)殛P(guān)閉此連接并創(chuàng)建一個(gè)新的連接將會(huì)改變輕量級(jí)的事務(wù)為分布式事務(wù)。

注意:多線程中共享在一個(gè) transaction scope 中的同一事務(wù)將導(dǎo)致下列異常:“Transaction context in use by another session.”

創(chuàng)建可移植的數(shù)據(jù)庫(kù)應(yīng)用程序

如果應(yīng)用程序必須工作在多個(gè)數(shù)據(jù)庫(kù)類型下,有些問(wèn)題就必須要考慮。
Oracle
如果使用 LoadDataSet 方法加載數(shù)據(jù),它將不會(huì)轉(zhuǎn)換 Guid 和 Boolean 數(shù)據(jù)類型。這是因?yàn)榧軜?gòu)無(wú)法決定數(shù)據(jù)的值是 Guid 還是簡(jiǎn)單的 bype">">。數(shù)據(jù)將返回為 byte[ 列。
當(dāng)你為返回多個(gè)游標(biāo)的存儲(chǔ)過(guò)程創(chuàng)建 DbCommand 對(duì)象時(shí),必須傳遞一個(gè)對(duì)象數(shù)組到 GetStoredProcCommand 方法。數(shù)組的大小必須與由存儲(chǔ)過(guò)程返回的游標(biāo)數(shù)量相同。例如,下列代碼示范了如何為返回二個(gè)游標(biāo)的存儲(chǔ)過(guò)程傳遞對(duì)象數(shù)組到 GetStoredProcCommand 。

Database db = DatabaseFactory.CreateDatabase();
object results = new object2;
DbCommand dbCommand = db.GetStoredProcCommand("GetCustomersAndSuppliers", results);

如果存儲(chǔ)過(guò)程僅返回一個(gè)游標(biāo),則不必須傳遞對(duì)象數(shù)組。
用于創(chuàng)建可移植數(shù)據(jù)庫(kù)應(yīng)用程序的建議。
在此有一些用于創(chuàng)建可移植數(shù)據(jù)庫(kù)應(yīng)用程序的建議:

  • 避免用存儲(chǔ)過(guò)程參數(shù)名使用數(shù)據(jù)庫(kù)專用令牌。用于特定提供程序的 Database 派生類包含了調(diào)整需要的參數(shù)名的代碼。例如,在支持到 SQL Server 數(shù)據(jù)庫(kù)的存儲(chǔ)過(guò)程參數(shù)名中不要包含 "@" 字符。下列代碼展示了如何調(diào)用 AddInParameter 方法通過(guò)名稱 CategoryID 創(chuàng)建參數(shù)。當(dāng)使用 SqlDatabase 對(duì)象執(zhí)行此代碼時(shí),提供程序用 "@" 做為參數(shù)名的開頭。
Database db = DatabaseFactory.CreateDatabase();DbCommand dbCommand = db.GetStoredProcCommand("GetProductsByCategory");db.AddInParameter(dbCommand, "CategoryID", DbType.Int32, 100);
  • 總是通過(guò) database 對(duì)象獲取參數(shù)值。
  • 考慮后端關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)(RDBMS)的大小寫敏感。例如,在 SQL Server 2000 中的字符串比較是大小寫不敏感的,但是在 Oracle 8i 和 DB2 中是大小寫敏感的。要開發(fā)一個(gè)可移植的應(yīng)用程序,就必須編寫自己的比較邏輯為大小寫不敏感的或者強(qiáng)迫應(yīng)用程序僅為在比較操作中使用的列存儲(chǔ)大寫或小寫。
  • 避免使用 RDBMS 專用數(shù)據(jù)類型,例如 OracleBlob
  • 在執(zhí)行存儲(chǔ)過(guò)程時(shí)避免使用返回值,而是使用輸出參數(shù)。
  • 在添加參數(shù)到參數(shù)集合中時(shí),確認(rèn)在應(yīng)用程序代碼中的順序與數(shù)據(jù)庫(kù)中的順序相匹配。OLE DB 提供程序使用順序來(lái)執(zhí)行存儲(chǔ)過(guò)程而不是名稱,所以以正確的順序添加集合是很重要的。
  • 如果在應(yīng)用程序代碼必須使用內(nèi)聯(lián)的 SQL ,確認(rèn) SQL 語(yǔ)法對(duì)于應(yīng)用程序?qū)⑦\(yùn)行的數(shù)據(jù)庫(kù)類型都是可用的。
  • 避免傳遞 null 值到值類型的存儲(chǔ)過(guò)程參數(shù)。如果需要通過(guò) SQLJ 存儲(chǔ)過(guò)程使用 DB2 的可移植接口,這些做將可能無(wú)法正常工作。
處理異常

處理異常的策略在任何企業(yè)應(yīng)用程序中都是必不可少的。下列信息將幫助你添加數(shù)據(jù)訪問(wèn)應(yīng)用程序塊到管理異常的方法中去:

  • CreateDatabase 方法使用配置信息,其可能的結(jié)果在配置相關(guān)的異常中。
  • Database 方法使用 ADO.NET 和底層數(shù)據(jù)庫(kù)提供程序。由 ADO.NET 拋出的異常由數(shù)據(jù)訪問(wèn)應(yīng)用程序塊為度量的目的而捕獲,然后再次拋出。
  • 充分處理異常通常要求訪問(wèn)特定的異常類型。可以包

使用 CommandBehavior.CloseConnection 調(diào)用 ExecuteReader。它在 DataReader 關(guān)閉時(shí)關(guān)閉連接。如果在一個(gè) try 塊中使用 ExecuteReader ,可以添加一個(gè) finally 語(yǔ)句并關(guān)閉返回的 DataReader 對(duì)象,就像展示在下列示例中的一樣。

Database db = DatabaseFactory.CreateDatabase();
DbCommand dbCommand = db.GetStoredProcCommand("GetProductsByCategory"); 
IDataReader dataReader = null;
try
{
  //...
  dataReader = db.ExecuteReader(dbCommand);
}
catch(Exception ex)
{
  // Process exception
}
finally
{
  if (dataReader != null)
    dataReader.Close();
}

另一種方法是,可以包含 using 語(yǔ)句來(lái)銷毀 DataReader 對(duì)象,這將導(dǎo)致它的關(guān)閉,就像展示在下列示例中一樣。

Database db = DatabaseFactory.CreateDatabase();
DbCommand dbCommand = db.GetStoredProcCommand("GetProductsByCategory"); 
using (IDataReader dataReader = db.ExecuteReader(dbCommand))
{
    // Process results
}

對(duì)于在 .NET 中的異常管理的設(shè)計(jì)和實(shí)現(xiàn)原則,請(qǐng)參見異常管理架構(gòu)指南。

處理參數(shù)

絕大多數(shù)存儲(chǔ)過(guò)程接受用于輸入存儲(chǔ)過(guò)程或在輸出時(shí)設(shè)置的值的參數(shù)。就像使用 ADO.NET 一樣,數(shù)據(jù)訪問(wèn)應(yīng)用程序塊允許開發(fā)人員指定參數(shù)所有的屬性。這些屬性可以包括方向、數(shù)據(jù)類型和長(zhǎng)度。此方法叫做顯式參數(shù)處理。然而,為了方便,可以僅指定用于輸入?yún)?shù)的值。在這種情況下,應(yīng)用程序塊將查找并提供參數(shù)的屬性。此方法叫參數(shù)發(fā)現(xiàn)。
顯式參數(shù)處理
Database 類包含了不同的用于傳遞參數(shù)到存儲(chǔ)過(guò)程的方法。此類還包含了用于設(shè)置和測(cè)試這些參數(shù)的值的方法。這些方法如下:

  • AddParameter。此方法傳遞一個(gè)參數(shù)(輸入或輸出)到存儲(chǔ)過(guò)程。
  • AddInParameter。此方法傳遞輸入?yún)?shù)到一個(gè)存儲(chǔ)過(guò)程。
  • AddOutParameter。此方法添加了一個(gè)輸出參數(shù)到存儲(chǔ)過(guò)程。
  • GetParameterValue。此方法查找指定的參數(shù)的值。
  • SetParameterValue。此方法在使用同樣的連接和命令,但有不同的參數(shù)值時(shí)進(jìn)行多個(gè)插入時(shí)設(shè)置指定參數(shù)的值。


下列代碼示范了如何使用 AddInParameterAddOutParameter 指定參數(shù)。

Database db = DatabaseFactory.CreateDatabase();
string sqlCommand = "GetProductDetails";
DbCommand dbCommand = db.GetStoredProcCommand(sqlCommand);db.AddInParameter(dbCommand, "ProductID", DbType.Int32, 5);
db.AddOutParameter(dbCommand, "ProductName", DbType.String, 50);
db.AddOutParameter(dbCommand, "UnitPrice", DbType.Currency, 8);

注意:前面的代碼不包括專用于數(shù)據(jù)庫(kù)類型的參數(shù)名稱令牌。因此,代碼保留了跨多個(gè)不同數(shù)據(jù)庫(kù)提供程序的通用性。當(dāng)此代碼運(yùn)行于 SqlClient 數(shù)據(jù)提供程序時(shí)(并因此使用 SqlDatabase 類),下列代碼將與前面的代碼有著同樣的行為。然而,此代碼不能移植到其他的數(shù)據(jù)類型。

Database db = DatabaseFactory.CreateDatabase();
string sqlCommand = "GetProductDetails";
DbCommand dbCommand = db.GetStoredProcCommand(sqlCommand);db.AddInParameter(dbCommand, "@ProductID", DbType.Int32, 5);
db.AddOutParameter(dbCommand, "@ProductName", DbType.String, 50);
db.AddOutParameter(dbCommand, "@UnitPrice", DbType.Currency, 8);

使用列值做為參數(shù)輸入
UpdateDataSet 方法要求三個(gè)不同的命令:一個(gè)用于插入值,一個(gè)用于修改值,另一個(gè)用于刪除值。通常,這些命令用于存儲(chǔ)過(guò)程而不是 SQL 字符串。它們?cè)谡{(diào)用后保持由存儲(chǔ)過(guò)程使用的參數(shù)。代替指定用于存儲(chǔ)過(guò)程參數(shù)的值,來(lái)自 DataSet 的值被用作輸入。在這種情況下,AddInParameter 的適當(dāng)重載是接受源列做為參數(shù)的方法之一。
下列代碼展示了如何使用列值做為參數(shù)輸入。

Database db = DatabaseFactory.CreateDatabase();DbCommand insertCommand = db.GetStoredProcCommand("AddProduct");
db.AddInParameter(insertCommand, "ProductName", DbType.String, "ProductName", DataRowVersion.Current);
db.AddInParameter(insertCommand, "CategoryID", DbType.Int32, "CategoryID", DataRowVersion.Current);
db.AddInParameter(insertCommand, "UnitPrice", DbType.Currency, "UnitPrice", DataRowVersion.Current);

?

參數(shù)發(fā)現(xiàn)
使用數(shù)據(jù)訪問(wèn)應(yīng)用程序塊,開發(fā)人員可以指定用于參數(shù)的值,而不需要關(guān)于這些參數(shù)的任何其他信息。在使用參數(shù)發(fā)現(xiàn)時(shí),將要指定所有參數(shù),并設(shè)置所有輸出參數(shù)為 NULL
下列代碼示范了如何僅通過(guò)指定參數(shù)值而無(wú)其他屬性來(lái)使用 GetStoredProcCommand

Database db = DatabaseFactory.CreateDatabase();
string sqlCommand = "UpdateProduct";
DbCommand dbCommand = db.GetStoredProcCommand(sqlCommand, 11, "Queso Cabrales", 4, 25);


關(guān)于每個(gè)參數(shù)的信息(例如,它的數(shù)據(jù)類型)依賴是底層 ADO.NET 方法調(diào)用所需要的。為了提供這些信息,數(shù)據(jù)訪問(wèn)應(yīng)用程序塊使用 ADO.NET 中的 DeriveParameters 方法來(lái)查找參數(shù)信息。
因?yàn)?DeriveParameters 調(diào)用需要到后端數(shù)據(jù)庫(kù)的一次往返,應(yīng)用程序塊還提供了參數(shù)信息緩存。在第一次調(diào)用需要參數(shù)發(fā)現(xiàn)的特定存儲(chǔ)過(guò)程后,關(guān)于每個(gè)參數(shù)的信息都保存到了參數(shù)緩存中。這意味著對(duì)同樣的存儲(chǔ)過(guò)程的后繼調(diào)用將不需要往返。
在使用參數(shù)發(fā)現(xiàn)時(shí),最好的方法是指定所有的輸出參數(shù)為 NULL 。不需要為 Oracle 存儲(chǔ)過(guò)程提供游標(biāo)參數(shù),OracleDatabase 提供了它們。此對(duì)象假設(shè)游標(biāo)參數(shù)是存儲(chǔ)過(guò)程參數(shù)列表中的第一個(gè)參數(shù)。

轉(zhuǎn)載于:https://www.cnblogs.com/sczw-maqing/p/3375806.html

總結(jié)

以上是生活随笔為你收集整理的Enterprise Library 4 数据访问应用程序块的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。