连接字符串配置错误是最常见连不上原因,需核对Server、Database、认证方式;优先用Windows身份验证;SQL账号需赋权;用SqlConnectionStringBuilder构造连接串;增删改查必须参数化;DataReader需及时关闭;事务须正确提交或回滚。

用 SqlConnection 连数据库前,先确认连接字符串对不对
连不上最常见原因不是代码写错,而是连接字符串里 Server、Database、Integrated Security 或 User ID/Password 配错了。SQL Server 本地默认实例名是 . 或 (local),命名实例得写成 .\SQLEXPRESS;如果启用了 TCP/IP 但没开 SQL Server Browser 服务,命名实例可能连不上。
- Windows 身份验证优先用
Integrated Security=true,比硬写账号密码安全,也避免密码明文泄露风险 - 用 SQL 账号时,确保该用户在目标数据库里有
db_datareader/db_datawriter角色,光有登录名不够 - 连接字符串别拼接,用
SqlConnectionStringBuilder构造,它会自动处理特殊字符(比如密码含分号)
执行增删改查必须用 SqlCommand + 参数化查询
直接拼接字符串执行 SQL 是 SQL 注入温床,哪怕只是查一个用户输入的订单号,也得用参数。ADO.NET 的 Parameters 集合不是可选项,是强制项。
-
SELECT用ExecuteReader(),读完立刻调用reader.Close()或用using包裹,否则连接不释放 -
INSERT/UPDATE/DELETE用ExecuteNonQuery(),返回影响行数,可用于判断是否成功(比如if (rowsAffected == 0) throw new InvalidOperationException("记录不存在")) - 参数名要和 SQL 里的
@paramName完全一致,大小写敏感;AddWithValue看似方便,但类型推断不准(比如把空字符串当nvarchar(1)),建议显式用Add("@name", SqlDbType.NVarChar).Value = value
using var conn = new SqlConnection(connStr);
conn.Open();
using var cmd = new SqlCommand("SELECT Name FROM Users WHERE Id = @id", conn);
cmd.Parameters.Add("@id", SqlDbType.Int).Value = userId;
using var reader = cmd.ExecuteReader();
while (reader.Read()) {
Console.WriteLine(reader["Name"]);
}
SqlDataReader 读数据时别越界、别重读、别跨连接
常见错误是循环里反复调用 reader["ColumnName"] 却忘了字段名拼错,或者用索引 reader[0] 但 SQL 字段顺序变了,或者试图在 reader 关闭后还访问它。
- 用
reader.GetOrdinal("ColumnName")获取索引,比硬写数字更健壮;或者直接用列名——只要确保名字和 SELECT 中的别名完全一致 -
reader.Read()每次只推进一行,想重读必须重新执行命令,不能倒回去 -
SqlDataReader是“只进”且“连接依赖”的,它活着时SqlConnection必须保持打开状态;别把它传到方法外再读,容易引发Invalid operation. The connection is closed.
事务不是加个 SqlTransaction 就完事
多条 SQL 要么全成功要么全回滚,靠的是事务控制,但很多人漏了关键两步:没在 catch 里 Rollback(),或者 Commit() 后又去 Dispose 事务对象导致异常。
- 事务对象必须和连接绑定,创建时传入
conn.BeginTransaction(),所有命令都要指定cmd.Transaction = tran - 务必在
try外或finally里确保tran?.Dispose(),但Commit()和Rollback()只能调用一次,重复调用抛InvalidOperationException - 长事务会锁表,尽量缩短事务内操作时间;避免在事务里做文件读写、HTTP 请求等外部调用
SqlConnection 不是线程安全的,别在多个线程间共享一个实例;也别以为 using 一包就万事大吉,如果里面嵌套了异步操作或延迟执行逻辑,连接可能提前关闭。


















