兩大提供者架構差異
| 特性 | SqlClient (System.Data.SqlClient) | OleDb (System.Data.OleDb) |
| 架構 |
原生 Managed 代碼,直接使用 TDS 協定與 SQL Server 通訊 |
橋接層:Managed → Unmanaged OLE DB Provider (SQLOLEDB) → TDS |
| 相依性 |
零非託管相依,部署單純 |
需安裝 MDAC / Microsoft OLE DB Driver for SQL Server |
| 效能 |
最優:少一層轉換、連線池原生、參數化執行計畫重用最佳 |
略低:COM 互通、雙重封送、參數綁定額外開銷 |
| 功能支援 |
完整支援 SQL Server 專有功能 (TVP、FileStream、Always Encrypted、Columnstore 等) |
僅支援 OLE DB 標準功能集,新功能滯後 |
| 連線字串關鍵字 |
Server, Database, User ID, Password, Integrated Security, Application Name, Pooling, Encrypt, TrustServerCertificate |
Provider=SQLOLEDB (或 MSOLEDBSQL), Data Source, Initial Catalog, User ID, Password, Integrated Security=SSPI |
程式碼對比:查詢 Pubs 資料庫 Titles 表
SqlClient 版本 (推薦)
using System;
using System.Data.SqlClient;
class Program {
static void Main() {
const string connStr = "Server=.;Database=pubs;User ID=sa;Password=;Application Name=Demo;";
using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand("SELECT title FROM titles", conn)) {
conn.Open();
using (var reader = cmd.ExecuteReader()) {
while (reader.Read()) {
Console.WriteLine(reader["title"]);
}
}
}
}
}
OleDb 版本 (相容舊系統/異構資料源)
using System;
using System.Data.OleDb;
class Program {
static void Main() {
const string connStr = "Provider=SQLOLEDB;Data Source=.;Initial Catalog=pubs;User ID=sa;Password=;";
using (var conn = new OleDbConnection(connStr))
using (var cmd = new OleDbCommand("SELECT title FROM titles", conn)) {
conn.Open();
using (var reader = cmd.ExecuteReader()) {
while (reader.Read()) {
Console.WriteLine(reader["title"]);
}
}
}
}
}
關鍵差異深度解析
1. 參數化查詢語法
// SqlClient: 具名參數 @param
cmd.CommandText = "SELECT * FROM titles WHERE pub_id = @pid AND price > @minPrice";
cmd.Parameters.AddWithValue("@pid", "1389");
cmd.Parameters.AddWithValue("@minPrice", 15.0m);
// OleDb: 位置參數 ? (順序必須一致)
cmd.CommandText = "SELECT * FROM titles WHERE pub_id = ? AND price > ?";
cmd.Parameters.AddWithValue("@pid", "1389"); // 名稱僅供參考,實際按 Add 順序綁定
cmd.Parameters.AddWithValue("@minPrice", 15.0m);
2. 連線池行為
- SqlClient:依連線字串精確比對 (大小寫敏感) 分池,
Pooling=true 預設開啟
- OleDb:依 OLE DB 服務元件實作,行為較不可預期,建議明確關閉
OLE DB Services=-4 避免問題
3. 異構資料源統一存取
OleDb 唯一優勢:同一套程式碼可存取 SQL Server、Oracle、Access、Excel、CSV、DB2 等任何有 OLE DB Provider 的資料源。適合建立通用報表引擎、ETL 框架。
現代建議:.NET Core / .NET 5+ 時代的選擇
| 場景 | 推薦提供者 | NuGet 套件 |
| SQL Server 專用新專案 |
Microsoft.Data.SqlClient (SqlClient 核心重寫版) |
Microsoft.Data.SqlClient |
| 現有 System.Data.SqlClient 專案維護 |
繼續使用 System.Data.SqlClient (相容模式) |
System.Data.SqlClient |
| 跨資料源通用存取層 |
System.Data.OleDb 或 System.Data.Odbc |
System.Data.OleDb, System.Data.Odbc |
| 高效能微服務/雲原生 |
Microsoft.Data.SqlClient + Dapper/EF Core |
Microsoft.Data.SqlClient, Dapper, Microsoft.EntityFrameworkCore.SqlServer |
遷移檢查清單 (OleDb → SqlClient)
- 連線字串轉換:
Provider=SQLOLEDB;Data Source=... → Server=...;Database=...;
- 參數標記:
? → @paramName
- 參數順序:改為具名參數,移除順序依賴
- 資料型別對應:
OleDbType → SqlDbType (如 DBTYPE_WVARCHAR → NVarChar)
- 例外處理:
OleDbException → SqlException (錯誤碼不同)
- 測試驗證:執行計畫、參數嗅探、連線池行為、交易範圍