SqlDataAdapter

C# ADO.NET 使用 SqlDataAdapter 呼叫預存程序填入 DataSet

上一個章節使用 SqlDataReader向前唯讀的串流讀取;本單元使用 SqlDataAdapter,把預存程序查詢結果一次載入到DataSet(記憶體離線資料表),常拿來直接繫結 DataGridView 這類控制項。
SqlCommand(定義預存程序) → SqlDataAdapter.SelectCommandadapter.Fill(DataSet) 自動取回資料

範例

string connectionString = "Data Source=.;Initial Catalog=db;Integrated Security=SSPI;";
using (SqlConnection conn = new SqlConnection(connectionString))
{
    conn.Open();

    SqlCommand sqlCom = new SqlCommand();
    sqlCom.Connection = conn;
    sqlCom.CommandText = "myProc";
    // 指定要執行預存程序
    sqlCom.CommandType = CommandType.StoredProcedure;

    // 傳入預存程序的輸入參數
    SqlParameter param = new SqlParameter("@id", SqlDbType.Int, 8);
    param.Value = 4;
    param.Direction = ParameterDirection.Input;
    sqlCom.Parameters.Add(param);

    // 資料配接器
    SqlDataAdapter sqlDA = new SqlDataAdapter();
    sqlDA.SelectCommand = sqlCom;

    DataSet ds = new DataSet();
    // 填入資料,第二個參數是 DataSet 內部資料表名稱
    sqlDA.Fill(ds, "sdfdsf");

    // 繫結 WinForms 表格控制項
    this.dataGridView1.DataSource = ds.Tables[0];
}Code language: C# (cs)

更規範的範例

string connectionString = "Data Source=.;Initial Catalog=db;Integrated Security=SSPI;";
using (SqlConnection conn = new SqlConnection(connectionString))
{
    string procName = "myProc";
    using (SqlCommand sqlCom = new SqlCommand(procName, conn))
    {
        sqlCom.CommandType = CommandType.StoredProcedure;
        // 精簡參數寫法
        sqlCom.Parameters.Add("@id", SqlDbType.Int).Value = 4;

        SqlDataAdapter sqlDA = new SqlDataAdapter(sqlCom);
        DataSet ds = new DataSet();
        // 填入查詢結果,資料表別名 ArticleResult
        sqlDA.Fill(ds, "ArticleResult");

        // 繫結控制項
        dataGridView1.DataSource = ds.Tables["ArticleResult"];
        // 也可以使用索引存取:ds.Tables[0]
    }
}Code language: JavaScript (javascript)

程式解說

SqlDataAdapter.Fill() 的特性
  1. 自動開關連線:呼叫Fill時如果連線尚未 Open(),配接器會自動開啟連線,執行完畢後自動關閉;

範例程式手動呼叫了conn.Open(),這麼寫可以,但並非必要。

  1. Fill(ds, "資料表名"):幫載入記憶體的 DataTable 命名,方便後續以名稱查找;若不指定,預設名稱為Table
  2. 當預存程序回傳多個結果集Fill會自動產生多個 DataTable:ds.Tables[0]、ds.Tables[1]...
DataSet 與 SqlDataReader 核心比較
物件模式連線佔用適用場景
SqlDataReader連線式串流讀取持續佔用資料庫連線大量資料、不需要完整快取、逐筆處理
DataSet(DataAdapter)離線記憶體快取Fill 完成就釋放連線UI控制項繫結、小量資料集、重複讀取資料

執行預存程序必要設定

sqlCom.CommandType = CommandType.StoredProcedure;

少了這一行,ADO.NET 會把 myProc 當成一般 SQL 文字執行,直接拋出錯誤。

控制項繫結

dataGridView1.DataSource = ds.Tables[0];

WinForms 的 DataGridView 可直接繫結 DataTable,自動產生資料行;
如果後續要修改資料並寫回資料庫,可以搭配 SqlDataAdapter.Update() 完成批次更新。

不手動開啟資料庫連線

using(SqlConnection conn=new SqlConnection(connectionString))
using(SqlCommand cmd=new SqlCommand("myProc",conn))
{
    cmd.CommandType=CommandType.StoredProcedure;
    cmd.Parameters.Add("@id",SqlDbType.Int).Value=4;
    SqlDataAdapter da=new SqlDataAdapter(cmd);
    DataSet ds=new DataSet();
    da.Fill(ds,"Article"); // 自動開啟、關閉連線
}Code language: JavaScript (javascript)

上面範例透過 using 管理連線資源

SqlDataAdapter

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *