从 ADO.NET 开始
VB.NET 访问数据库主要依赖 ADO.NET。核心对象是 SqlConnection、SqlCommand、SqlDataReader 和 SqlDataAdapter。选择提供程序时,SQL Server 用 System.Data.SqlClient,其他数据库用对应的 OleDb 或第三方驱动。
连接字符串建议放在配置文件(如 App.config)中,通过 ConfigurationManager.ConnectionStrings 读取,避免硬编码。
连接管理与资源释放
数据库连接是稀缺资源,必须及时关闭。推荐用 Using 语句自动释放:
vb.net
Using conn As New SqlConnection(connStr)
conn.Open()
Using cmd As New SqlCommand(“SELECT Name FROM Users”, conn)
Using reader = cmd.ExecuteReader()
While reader.Read()
Console.WriteLine(reader(“Name”))
End While
End Using
End Using
End Using
Using 实际会在异常时也保证 Dispose 被调用,比手动 Close 更稳妥。
参数化查询是底线
拼接 SQL 字符串是 SQL 注入的根源。正确做法是用参数占位:
vb.net
cmd.CommandText = “SELECT * FROM Users WHERE Name = @name”
cmd.Parameters.AddWithValue(“@name”, userName)
AddWithValue 方便,但类型推断可能不精确。对日期、decimal、varchar 长度敏感的场景,建议显式指定 SqlDbType 与 Size,既避免隐式转换,也有助于执行计划复用。
DataReader 与 DataTable 怎么选
SqlDataReader 是只进只读流式读取,内存占用小,适合遍历大量数据;DataTable 把结果一次性载入内存,支持排序、筛选和绑定控件,适合小数据集或需要离线操作的场景。用 SqlDataAdapter.Fill 填充 DataTable 是最简洁的写法。
事务与异常处理
涉及多条写操作时,用 SqlTransaction 保证原子性:
vb.net
Using tran = conn.BeginTransaction()
Try
‘ 多条命令,Transaction 属性指向 tran
tran.Commit()
Catch ex As Exception
tran.Rollback()
Throw
End Try
End Using
捕获异常时不要吞掉,至少记录日志后重新抛出,便于定位问题。
连接池与性能提示
ADO.NET 默认启用连接池。频繁 Open/Close 并不是问题,真正拖慢性能的是长时间占用连接或连接字符串不一致导致池失效。保持连接字符串完全一致,查询后立即释放,能显著提升并发表现。此外,只查询需要的列、避免 SELECT *,配合合理索引,往往比代码层优化收益更大。