C# ADO.NET 调用存储过程填充 DataSet,基于SqlDataAdapter
上一节使用 SqlDataReader 流式向前只读读取;本节使用 SqlDataAdapter,把存储过程查询结果一次性载入 DataSet(内存离线数据表),常用于直接绑定 DataGridView 等控件。SqlCommand(定义存储过程) → SqlDataAdapter.SelectCommand → adapter.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() 特性
- 自动开关连接:如果调用
Fill时连接没有Open(),适配器会自动打开连接,执行完成后自动关闭;
示例代码手动写了
conn.Open(),属于可行写法,但不是必需。
Fill(ds, "表名"):给载入内存的DataTable命名,方便后续按名称查找,不指定则默认名称Table。- 存储过程返回多个查询结果集时,
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来连接
Previous: SqlDataReader
Next: 存储过程 Return