首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Microsoft Data Access Application Block 深度解析:企業級資料存取元件最佳實踐

     編輯:關於.NET

在早期 .NET 開發時代,重複撰寫 ADO.NET 連線、命令、參數、資源釋放等樣板代碼是常態。Microsoft Patterns & Practices 團隊推出的 Data Access Application Block (DAAB),將資料存取最佳實踐封裝為可重用組件,大幅簡化 SQL Server 操作。雖然現代開發多轉向 Entity Framework Core 或 Dapper,但 DAAB 的設計思想與核心模式仍具參考價值。

核心價值:為什麼需要 DAAB?

  • 消除樣板代碼:連線開啟/關閉、命令建立、參數綁定、DataReader/DataSet 填充、異常處理與資源釋放,全部內建於靜態方法中。
  • 內建最佳實踐:連線池管理、參數快取、命令準備、交易支援等企業級需求開箱即用。
  • 原始碼開放:可直接引用組件,亦可下載原始碼客製化擴充(如支援其他資料庫、加入攔截器、日誌記錄等)。

核心類別架構

SqlHelper:靜態門面類別

提供五大核心靜態方法,每種方法皆有多重載支援 SqlConnection、SqlTransaction、連線字串、CommandType、參數陣列等組合:

  • ExecuteNonQuery:執行不傳回資料列的命令(INSERT/UPDATE/DELETE),回傳影響列數。
  • ExecuteDataset:傳回 DataSet,適合斷線式多資料表操作。
  • ExecuteReader:傳回 SqlDataReader,高效能、唯讀、前向游標。
  • ExecuteScalar:傳回單一值(第一列第一欄)。
  • ExecuteXmlReader:執行 FOR XML 查詢,傳回 XmlReader。

SqlHelperParameterCache:參數快取引擎

解決重複發現預存程序參數元資料的效能問題:

  • CacheParameterSet:手動快取參數集合(Key = 連線字串 + 命令文字)。
  • GetCachedParameterSet:取得快取參數副本,避免原始快取被修改。
  • GetSpParameterSet:自動發現預存程序參數(首次查詢 sys.parameters,後續走快取),支援 SqlCommandBuilder.DeriveParameters。

實戰代碼範例

單行代碼呼叫預存程序並取得 DataSet

// C#
DataSet ds = SqlHelper.ExecuteDataset(
    connectionString,
    CommandType.StoredProcedure,
    "GetProductsByCategory",
    new SqlParameter("@CategoryID", categoryID));

參數快取與重用

const string CONN_STRING = "Server=.;Database=Northwind;Integrated Security=True;";
string sql = "SELECT ProductName FROM Products WHERE Category=@Cat AND SupplierID=@Sup";

// 快取參數定義
SqlParameter[] paramsToStore = {
    new SqlParameter("@Cat", SqlDbType.Int),
    new SqlParameter("@Sup", SqlDbType.Int)
};
SqlHelperParameterCache.CacheParameterSet(CONN_STRING, sql, paramsToStore);

// 後續使用:取得副本、設定值、執行
SqlParameter[] storedParams = SqlHelperParameterCache.GetCachedParameterSet(CONN_STRING, sql);
storedParams[0].Value = 2;
storedParams[1].Value = 3;
DataSet ds = SqlHelper.ExecuteDataset(CONN_STRING, CommandType.Text, sql, storedParams);

自動發現預存程序參數


SqlParameter[] spParams = SqlHelperParameterCache.GetSpParameterSet(CONN_STRING, "SalesByCategory");
spParams[0].Value = "Beverages";
spParams[1].Value = 1997;
DataSet ds = SqlHelper.ExecuteDataset(CONN_STRING, CommandType.StoredProcedure, "SalesByCategory", spParams);

內部設計亮點

  • PrepareCommand 統一管線:所有公開方法最終均委派給私有 PrepareCommand 設定 SqlCommand 屬性(Connection、Transaction、CommandType、CommandText、Parameters),確保行為一致。
  • AttachParameters / AssignParameterValues:分離參數綁定與賦值邏輯,支援陣列參數與名值對參數兩種模式。
  • 參數深層複製:快取回傳前先 CloneParameters,防止呼叫端修改影響快取原始值。
  • 不可繼承設計:SqlHelper 為 sealed 類別且建構函式為 private,強制靜態使用,避免誤用狀態。

常見問題與決策指南

問題建議
ExecuteDataset vs ExecuteReader? 需斷線式、多資料表、XML 序列化、繫結 UI 控制項 → DataSet;需極致效能、大量資料串流、唯讀前向 → DataReader。
如何傳回多資料表 DataSet? 建立主預存程序巢狀呼叫多個 SELECT 預存程序,單次 ExecuteDataset 即可取得多 Table(Table、Table1...)。
支援 XCOPY 部署? 支援,編譯產出的 Microsoft.ApplicationBlocks.Data.dll 為純 managed 組件,可直接複製部署。
為何 ExecuteXmlReader 不支援連線字串? XmlReader 關閉時無法自動關閉關聯連線,若由內部建立連線將導致洩漏,故強制要求呼叫端管理連線生命週期。

遷移建議:從 DAAB 邁向現代架構

雖 DAAB 仍可穩定運作,但新專案建議考慮:

  • Dapper:輕量 Micro-ORM,效能極高,語法貼近 SQL,支援多資料庫。
  • Entity Framework Core:完整 ORM,支援 LINQ、遷移、變更追蹤、多提供者。
  • Microsoft.Data.SqlClient:官方最新 SQL Server 驅動,支援 Always Encrypted、Data Classification 等新特性。

若維護舊系統,DAAB 依然是可靠選擇;其「靜態門面 + 參數快取 + 統一命令管線」的設計模式,在自建資料存取庫時同樣適用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved