.NET 數(shù)據(jù)訪問體系結(jié)構(gòu)向?qū)б?/h1>
發(fā)表時間:2024-06-02 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
ADO.NET 引入的主要變化之一是用 DataTable、DataSet、DataAdapter 和 DataReader 對象的組合取代了 ADO Recordset 對象。DataTable 表示單個表中行的集合,在這一方面類似于 Recordset。DataSet 表示 DataTable 對象的集合,同時包括將各種表綁定在一起的關(guān)系和約束。實際上,DataSet 是帶有內(nèi)置 XML 支持的、內(nèi)存中的關(guān)系結(jié)構(gòu)。
DataSet 的主要特性之一是它不了解可能用來填充它的基礎(chǔ)數(shù)據(jù)源。它是一個不連續(xù)的、獨立的實體,用于表示數(shù)據(jù)集合,并且可以通過多層應(yīng)用程序的不同層在組件之間傳遞。它還可以作為 XML 數(shù)據(jù)流進行序列化,這使其非常適合于在不同種類的平臺之間進行數(shù)據(jù)傳輸。ADO.NET 使用 DataAdapter 對象將數(shù)據(jù)傳送到 DataSet 和基礎(chǔ)數(shù)據(jù)源,或者從數(shù)據(jù)源傳出。DataAdapter 對象還提供以前與 Recordset 關(guān)聯(lián)的增強的批量更新功能。
ADO.NET 依賴于 .NET 數(shù)據(jù)提供程序的服務(wù)。這些提供程序提供對基礎(chǔ)數(shù)據(jù)源的訪問,并且包括四個主要對象(Connection、Command、DataReader 和 DataAdapter)。
目前,ADO.NET 隨附了兩類提供程序:Bridge 提供程序和 Native 提供程序。通過 Bridge 提供程序(如那些為 OLE DB 和 ODBC 提供的提供程序),可以使用為以前的數(shù)據(jù)訪問技術(shù)設(shè)計的數(shù)據(jù)庫。Native 提供程序(如 SQL Server 和 Oracle 提供程序)通常能夠提供性能方面的改善,部分原因在于少了一個抽象層。
命名空間組織結(jié)構(gòu)
與各個 .NET 數(shù)據(jù)提供程序相關(guān)聯(lián)的類型(類、結(jié)構(gòu)、枚舉等)位于其各自的命名空間中:
• | System.Data.SqlClient。包含 SQL Server .NET 數(shù)據(jù)提供程序類型。 |
• | System.Data.OracleClient。包含 Oracle .NET 數(shù)據(jù)提供程序。 |
• | System.Data.OleDb。包含 OLE DB .NET 數(shù)據(jù)提供程序類型。 |
• | System.Data.Odbc。包含 ODBC .NET 數(shù)據(jù)提供程序類型。 |
• | System.Data。包含獨立于提供程序的類型,如 DataSet 和 DataTable。 |
在各自的關(guān)聯(lián)命名空間內(nèi),每個提供程序都提供了對 Connection、Command、DataReader 和 DataAdapter 對象的實現(xiàn)。SqlClient 實現(xiàn)的前綴為“Sql”,而 OleDb 實現(xiàn)的前綴為“OleDb”。例如,Connection 對象的 SqlClient 實現(xiàn)是 SqlConnection,而 OleDb 實現(xiàn)則為 OleDbConnection。同樣,DataAdapter 對象的兩個實現(xiàn)分別為 SqlDataAdapter 和 OleDbDataAdapter。
存儲過程與直接 SQL
本文檔中顯示的大多數(shù)代碼片段使用 SqlCommand 對象來調(diào)用存儲過程,以執(zhí)行數(shù)據(jù)庫操作。在某些情況下,您將不會看到 SqlCommand 對象,因為存儲過程名被直接傳遞給 SqlDataAdapter 對象。在內(nèi)部,這仍然會導(dǎo)致創(chuàng)建 SqlCommand 對象。
您應(yīng)該使用存儲過程而不是嵌入的 SQL 語句,原因如下:
• | 存儲過程通常可以改善性能,因為數(shù)據(jù)庫能夠優(yōu)化存儲過程使用的數(shù)據(jù)訪問計劃,并且能夠緩存該計劃以供將來重用。 |
• | 可以在數(shù)據(jù)庫內(nèi)分別設(shè)置各個存儲過程的安全保護。客戶端不必對基礎(chǔ)表擁有訪問權(quán)限,就可以獲得執(zhí)行存儲過程的權(quán)限。 |
• | 存儲過程可以簡化維護工作,因為修改存儲過程通常要比更改已部署組件中的硬編碼 SQL 語句容易。 |
• | 存儲過程為基礎(chǔ)數(shù)據(jù)庫架構(gòu)增加了額外的抽象級別。存儲過程的客戶端與存儲過程的實現(xiàn)細節(jié)是彼此隔離的,與基礎(chǔ)架構(gòu)也是彼此隔離的。 |
• | 存儲過程可以減少網(wǎng)絡(luò)流量,因為可以批量執(zhí)行 SQL 語句,而不是從客戶端發(fā)送多個請求。 |
SQL Server 聯(lián)機文檔強烈建議您不要使用“sp_”作為名稱前綴來創(chuàng)建任何存儲過程,因為此類名稱已經(jīng)被指定給系統(tǒng)存儲過程。SQL Server 始終按以下順序來查找以 sp_ 開頭的存儲過程:
1. | 在主數(shù)據(jù)庫中查找存儲過程。 |
2. | 基于所提供的任何限定符(數(shù)據(jù)庫名或所有者)來查找存儲過程。 |
3. | 使用 dbo 作為所有者來查找存儲過程(如果未指定所有者)。 |
屬性與構(gòu)造函數(shù)參數(shù)
可以通過構(gòu)造函數(shù)參數(shù)來設(shè)置 ADO.NET 對象的特定屬性值,也可以直接設(shè)置屬性值。例如,下面的代碼片段在功能上是等效的。
// Use constructor arguments to configure command objectSqlCommand cmd = new SqlCommand( "SELECT * FROM PRODUCTS", conn );// The above line is functionally equivalent to the following// three lines which set properties explicitlysqlCommand cmd = new SqlCommand();cmd.Connection = conn;cmd.CommandText = "SELECT * FROM PRODUCTS";
從性能角度看,這兩種方法之間的差異是微不足道的,因為針對 .NET 對象設(shè)置和獲取屬性要比針對 COM 對象執(zhí)行類似操作更為高效。
選擇哪種方法取決于個人喜好和編碼風(fēng)格。不過,對屬性進行明確設(shè)置確實能夠使代碼更易理解(尤其是當您不熟悉 ADO.NET 對象模型時)和調(diào)試。
管理數(shù)據(jù)庫連接
數(shù)據(jù)庫連接代表一種關(guān)鍵的、昂貴的和有限的資源,尤其是在多層 Web 應(yīng)用程序中。正確地管理連接是十分必要的,因為您采取的方法可能顯著影響應(yīng)用程序的總體可伸縮性。同時,還要認真考慮在何處存儲連接字符串。需要使用可配置的且安全的位置。
在管理數(shù)據(jù)庫連接和連接字符串時,應(yīng)該努力做到:
• | 通過在多個客戶端中多路復(fù)用數(shù)據(jù)庫連接池,幫助實現(xiàn)應(yīng)用程序的可伸縮性。 |
• | 采用可配置的、高性能的連接池策略。 |
• | 在訪問 SQL?Server 時使用 Windows 身份驗證。 |
• | 在中間層避免模擬。 |
• | 安全地存儲連接字符串。 |
• | 盡量晚地打開數(shù)據(jù)庫連接,盡量早地將其關(guān)閉。 |
本節(jié)討論連接池,并且?guī)椭x擇適當?shù)倪B接池策略。本節(jié)還將考慮應(yīng)該如何管理、存儲和操縱數(shù)據(jù)庫連接字符串。最后,本節(jié)將給出兩種編碼模式,可用來幫助確保連接被可靠地關(guān)閉,并被返回到連接池。
SQL Server .NET 數(shù)據(jù)提供程序的池機制
如果您使用的是 SQL Server .NET 數(shù)據(jù)提供程序,請使用該提供程序提供的連接池支持。這是一種由該提供程序在內(nèi)部實現(xiàn)的支持事務(wù)處理并且非常高效的機制,它存在于托管代碼中。池是以每個應(yīng)用程序的域為基礎(chǔ)創(chuàng)建的,并且在應(yīng)用程序域卸載之前不會銷毀。
可以透明地使用這種形式的連接池,但應(yīng)該知道池的管理方式以及可用來微調(diào)連接池的各種配置選項。
在許多情況下,對于您的應(yīng)用程序而言,SQL Server .NET 數(shù)據(jù)提供程序的默認連接池設(shè)置可能已經(jīng)足夠了。在開發(fā)和測試基于 .NET 的應(yīng)用程序的過程中,建議您對規(guī)劃通信模式進行模擬,以確定是否需要修改連接池大小。
需要生成可伸縮的高性能應(yīng)用程序的開發(fā)人員應(yīng)該最大限度地減少使用連接的時間,只在檢索或更新數(shù)據(jù)時才使連接保持打開狀態(tài)。連接關(guān)閉時,將被返回到連接池,并可供重用。在此情況下,到數(shù)據(jù)庫的實際連接不會被切斷;不過,如果連接池被禁用,則到數(shù)據(jù)庫的實際連接將被關(guān)閉。
開發(fā)人員應(yīng)該十分小心,不要依賴垃圾回收器來釋放連接,因為當引用離開作用范圍時,連接未必能夠關(guān)閉。這是連接泄漏的一種常見根源,當請求新連接時,這會導(dǎo)致連接異常。
配置 SQL Server .NET 數(shù)據(jù)提供程序連接池
可以使用一組名稱-值對(通過連接字符串提供)來配置連接池。例如,可以配置是否啟用連接池(默認情況下啟用)、池的最大容量和最小容量,以及要打開連接的排隊請求可以阻塞的時間長度。下面是一個示例連接字符串,用于配置池的最大容量和最小容量。
"Server=(local); Integrated Security=SSPI; Database=Northwind; Max Pool Size=75; Min Pool Size=5"
打開連接并創(chuàng)建池以后,會將多個連接添加到池中,以便將連接數(shù)量提高到所配置的最小數(shù)量。隨后,可以繼續(xù)向該池中添加連接,直至達到所配置的最大池數(shù)量。當達到最大數(shù)量時,要打開連接的新請求將排隊等待一段可配置的時間。