歡迎光臨
每天分享高質量文章

.NET Core 3.0 中的資料庫驅動框架 System.Data

雖然沒有得到很多關註,但System.Data對於.NET 中任何關係型資料庫的訪問都至關重要。因為其前身是 ActiveX Data Objects,所以它也被稱為 ADO.NET。System.Data 提供了一個通用框架,是構建.NET 資料庫驅動程式的基礎。該框架提供了資料庫驅動可以遵循的具體規範。

連線、命令和資料讀取器都基於雙重繼承樣式。它們分別從 DbConnection、DbCommand 和 DbDataReader 繼承了一些基本功能。它們還實現了抽象介面 IDbConnection、IDbCommand 和 IDbDataReader,這些介面可以模擬場景和非傳統資料源。這種雙重繼承樣式也適用於下麵描述的所有基類。

雖然連線字串通常被視為字串,但有一些工具可以將它們表示為從 DbConnectionStringBuilder 繼承的物件。這可以處理特定資料庫的連線字串解析,並使開發人員可以更好地瞭解特定資料庫提供的設定。

System.Data 早於 ORMs for .NET,但它確實提供了一種透過實現 DbDataAdapter 和 DbCommandBuilder 類生成 SQL 的通用方法。這既可以直接使用,也可以與普通資料集和型別化資料集結合使用。

如果你正在尋找抽象工廠樣式的真實示例,請檢視 DbProviderFactory。它的子類提供了連線、命令、命令引數、命令構建器和資料配接器。基本上是資料訪問所需的一切,而不需要特定於資料庫的邏輯。

介面的問題

如上所述,System.Data 依賴於雙重繼承。在新增新方法時,這可能是一個問題。例如,.NET 4.5 中的 DbCommand 增加了非同步操作。但是,它們無法新增到相應的 IDbCommand 介面中,因為這將是一個破壞性更改。這意味著你不能同時使用非同步操作和容易模擬的抽象介面。

微軟本可以在.NET Core 1.0 中一次性重置抽象介面,使其與抽象類相匹配(Java 過去在 JDBC 介面中就這樣做過)。然而,這會使與.NET Framework 共享程式碼變得困難。

如果 C# 8 中包含預設介面方法,那麼理論上可以使用它們以向後相容的方式重新組合介面。但是,由於預設介面方法是.NET Core 才有的特性,所以它與.NET Framework 不相容,也就不能用於舊的編譯器和其他.NET 語言。

DbDataReader.Get() 字串多載 #31595*

.NET Core 3.0 的第一個特性是能夠將列名傳遞給 DbDataReader.GetXXX 方法。長期以來,人們一直抱怨這個介面不能按名稱取用列。這意味著你需要使用下麵這個樣式:


reader.GetInt32(reader.GetOrdinal(“columnName”))

顯然(對有些人來說,早就該這樣了),簡化方式是提供一個字串多載( string overload):

 


reader.GetInt32(“columnName”)

Oracle 的 Connector/NET 和MySqlConnector已經這樣做了。

因為效能原因,這個新方法不會被標記為 virtual,從而使 JIT 編譯器可以輕鬆地將它行內。由於上述原因,新的方法集不會新增到 IDbDataReader 中。

XmlDataDocument #33442

如果你瞭解XmlDataDocument的歷史,那麼這似乎是一個奇怪的選擇。自從.NET 4.0 在 2010 年釋出以來,它就已經被標記為過時,並警告說“XmlDataDocument 類將在未來的版本中被刪除”。

現在重新開始使用它的原因是一些 WinForms 和 WPF 應用程式在使用它。Bug 報告顯示,“它在 Apiport 的不同類別中有 1-7% 的使用率。”

DatasetExtensions

.NET Core 3 中沒有的一個特性是DataTableExtensions類。雖然看起來非常簡單,只有 6 個擴充套件方法,但是如果不修改 System.Data 本身,就無法構建 AsDataView。原因相當複雜,涉及內部方法、型別轉發和.NET 標準帶來的挑戰。

如果你感興趣,可以看下相關的話題,包括“將 DatasetExtensions 移植到.NET Core #19771”、“移植 DataTable.AsDataView 擴充套件方法 #27610”和“公開涉及在 DataView 中進行鍵搜尋的內部虛擬方法 #31764”。

贊(0)

分享創造快樂