SqlDataAdapter

C# ADO.NET 调用存储过程填充 DataSet,基于SqlDataAdapter

上一节使用 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 vs SqlDataReader 核心对比
对象模式连接占用适用场景
SqlDataReader在线流式读取持续占用数据库连接大量数据、不需要全部缓存、逐条处理
DataSet(DataAdapter)离线内存缓存Fill完成后立刻释放连接UI控件绑定、小数据集、多次重复读取数据

执行存储过程必须配置项

sqlCom.CommandType = CommandType.StoredProcedure;

缺少这一行,ADO.NET会把myProc当成普通SQL文本执行,直接报错。

控件绑定

dataGridView1.DataSource = ds.Tables[0];

WinForms DataGridView 支持直接绑定 DataTable,自动生成列;
如果后续需要修改数据并写回数据库,还可以搭配 SqlDataAdapter.Update() 实现批量更新。

不手动Open连接

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来连接

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注