在 C# 开发中,和数据库打交道是家常便饭,而 ADO.NET 就是我们操作数据库的“得力助手”。
它的核心对象各司其职,搭配起来即可完成数据的 增、删、改、查。
本文将系统梳理 ADO.NET 的核心对象、协作流程,并提供 完整可用的分页查询实战代码,非常适合作为学习笔记或博客文章直接发布。
一、ADO.NET 核心对象(一个都不能少)
ADO.NET 的数据库操作围绕以下几个核心对象展开,它们分工明确、各司其职。
1️⃣ Connection —— 数据库的“连接器”
作用:
负责建立应用程序与数据库之间的物理连接,没有它,所有数据库操作都无法进行。
常用方法:
Open():打开数据库连接Close():关闭数据库连接
Close vs Dispose 的区别:
| 方法 | 说明 |
|---|---|
| Close() | 关闭连接,但对象仍可再次 Open() |
| Dispose() | 释放所有资源,对象不可再使用 |
✅ 最佳实践:使用 using 语句,自动释放资源。
2️⃣ Command —— 数据库的“指令官”
作用:
依附于 Connection,用于向数据库发送 SQL 指令或调用存储过程。
核心属性:
CommandText:SQL 语句或存储过程名Connection:关联的数据库连接CommandType:Text/StoredProcedure
常用方法:
ExecuteNonQuery():执行增删改,返回受影响行数ExecuteScalar():返回第一行第一列的值ExecuteReader():返回DataReader
3️⃣ DataAdapter —— 数据的“搬运工”
作用:
连接 数据库 与 DataSet 的桥梁,负责数据的读取与回写。
核心方法:
Fill():从数据库填充 DataSetUpdate():将 DataSet 的更改同步回数据库
📌 特点:
- 无需手动管理连接
Fill()会自动打开并关闭连接
4️⃣ DataSet —— 内存中的“数据库副本”
作用:
用于在内存中暂存数据,完全脱离数据库连接进行操作。
组成结构:
DataSet
├── DataTable
│ ├── DataRow
│ └── DataColumn
优势:
- 支持离线操作
- 可保存表结构、主键、表关系
- 适合复杂业务处理
5️⃣ DataReader —— 高性能“数据阅读器”
适用场景:
只读、高性能、顺序读取数据。
核心特点:
- 只读(ReadOnly)
- 只进(ForwardOnly)
- 极低内存占用
⚠️ 注意事项:
- 使用期间 Connection 必须保持打开
- 读取完成后必须及时关闭连接
二、ADO.NET 核心对象协作流程
完整的数据库操作流程如下:
- 使用
Connection打开数据库连接 - 使用
Command或DataAdapter执行 SQL - 查询结果:
- 快速读取 →
DataReader - 离线操作 →
DataSet / DataTable
- 快速读取 →
- 执行业务逻辑处理
三、实战示例:ADO.NET 分页查询(完整版)
以下示例基于 ROW_NUMBER() 实现分页,包含:
- 参数化 SQL
- DataSet 查询
- DataTable 转实体
1️⃣ 业务层:分页入口
public List<Books> GetPageList(int pageIndex, int pageSize)
{
int start = (pageIndex - 1) * pageSize + 1;
int end = pageIndex * pageSize;
DataSet ds = dal.GetPageList(start, end);
return DataTableToList(ds.Tables[0]);
}
2️⃣ 数据访问层:分页 SQL
public DataSet GetPageList(int start, int end)
{
string sql = @"
SELECT *
FROM (
SELECT *, ROW_NUMBER() OVER(ORDER BY Id) AS Num
FROM Books
) t
WHERE t.Num >= @start AND t.Num <= @end";
SqlParameter[] ps =
{
new SqlParameter("@start", SqlDbType.Int),
new SqlParameter("@end", SqlDbType.Int)
};
ps[0].Value = start;
ps[1].Value = end;
return SqlHelper.Query(sql, CommandType.Text, ps);
}
3️⃣ DataTable → 实体列表
public List<Books> DataTableToList(DataTable dt)
{
List<Books> list = new List<Books>();
foreach (DataRow row in dt.Rows)
{
Books model = new Books();
model.Id = row["Id"] != DBNull.Value ? Convert.ToInt32(row["Id"]) : 0;
model.Title = row["Title"].ToString();
model.Author = row["Author"].ToString();
model.ISBN = row["ISBN"].ToString();
if (row["PublishDate"] != DBNull.Value)
model.PublishDate = Convert.ToDateTime(row["PublishDate"]);
if (row["UnitPrice"] != DBNull.Value)
model.UnitPrice = Convert.ToDecimal(row["UnitPrice"]);
list.Add(model);
}
return list;
}
四、ADO.NET 实战优化技巧(必看)
✅ 1. 使用配置文件管理连接字符串
- App.config / Web.config
- 避免硬编码,方便环境切换
✅ 2. 封装 SqlHelper 工具类
- 统一管理 Connection / Command
- 减少重复代码,提高可维护性
✅ 3. 坚决使用参数化查询
- 防止 SQL 注入
- 提升 SQL 执行计划复用率
✅ 4. using 语句释放资源
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
...
}
五、总结
ADO.NET 虽然不像 EF Core 那样“开箱即用”,但它是 所有 ORM 框架的底层基础。
👉 理解 ADO.NET = 理解数据库访问本质
👉 会 ADO.NET = ORM 再复杂也不慌
👋 关注我吧!