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