在早期 .NET 開發時代,重複撰寫 ADO.NET 連線、命令、參數、資源釋放等樣板代碼是常態。Microsoft Patterns & Practices 團隊推出的 Data Access Application Block (DAAB),將資料存取最佳實踐封裝為可重用組件,大幅簡化 SQL Server 操作。雖然現代開發多轉向 Entity Framework Core 或 Dapper,但 DAAB 的設計思想與核心模式仍具參考價值。
提供五大核心靜態方法,每種方法皆有多重載支援 SqlConnection、SqlTransaction、連線字串、CommandType、參數陣列等組合:
ExecuteNonQuery:執行不傳回資料列的命令(INSERT/UPDATE/DELETE),回傳影響列數。ExecuteDataset:傳回 DataSet,適合斷線式多資料表操作。ExecuteReader:傳回 SqlDataReader,高效能、唯讀、前向游標。ExecuteScalar:傳回單一值(第一列第一欄)。ExecuteXmlReader:執行 FOR XML 查詢,傳回 XmlReader。解決重複發現預存程序參數元資料的效能問題:
CacheParameterSet:手動快取參數集合(Key = 連線字串 + 命令文字)。GetCachedParameterSet:取得快取參數副本,避免原始快取被修改。GetSpParameterSet:自動發現預存程序參數(首次查詢 sys.parameters,後續走快取),支援 SqlCommandBuilder.DeriveParameters。// 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 設定 SqlCommand 屬性(Connection、Transaction、CommandType、CommandText、Parameters),確保行為一致。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 依然是可靠選擇;其「靜態門面 + 參數快取 + 統一命令管線」的設計模式,在自建資料存取庫時同樣適用。