连接字符串写错会导致 SqlException
或超时
最常见的失败不是代码逻辑问题,而是
connectionString格式或参数不匹配。SQL Server 支持 Windows 身份验证和 SQL Server 身份验证两种方式,二者连接字符串结构差异明显: Windows 身份验证(推荐开发环境):
"Server=localhost\SQLEXPRESS;Database=MyDB;Trusted_Connection=True;"SQL Server 身份验证(常见于生产或远程实例):
"Server=192.168.1.100,1433;Database=MyDB;User Id=myuser;Password=mypass;"
注意:
localhost\SQLEXPRESS中的双反斜杠是 C# 字符串转义要求;若用逐字字符串(
@""),应写作
@"localhostSQLEXPRESS"。端口未显式指定时默认为 1433,但命名实例(如
SQLEXPRESS)必须启用 SQL Server Browser 服务,否则可能连不上。
SqlConnection
必须显式调用 Open()
才建立物理连接
new SqlConnection(connectionString)只创建对象,不触发网络连接。真正握手发生在调用
Open()时——这也是异常最常抛出的位置。务必用
try/catch包裹,并检查
SqlException.Number做针对性处理:
try
{
using (var conn = new SqlConnection(connStr))
{
conn.Open(); // ← 真正连接在此发生
// 后续操作
}
}
catch (SqlException ex)
{
switch (ex.Number)
{
case 2: Console.WriteLine("服务器不可达,请检查网络或实例名");
case 18456: Console.WriteLine("登录失败,用户名或密码错误");
case 4060: Console.WriteLine("数据库名不存在或无法访问");
default: throw;
}
}使用 using
语句确保连接及时释放
SQL Server 连接数有限(尤其 Express 版默认最大 10000),不释放会快速耗尽资源,后续请求直接卡在
Open()等待。C# 的
using不仅自动调用
Dispose(),还会隐式调用
Close()—— 即使发生异常也能保证清理: ❌ 错误写法:
var conn = new SqlConnection(...); conn.Open(); /* 忘记 close/dispose */✅ 正确写法:
using (var conn = new SqlConnection(...)) { conn.Open(); /* 自动关闭 */ }
注意:
SqlConnection实现了连接池,默认开启。调用
Close()并非断开 TCP,而是将连接归还池中复用。因此频繁
new+
Close()是安全且高效的,不必手动缓存
SqlConnection对象。
查询执行前确认数据库状态和权限
连接成功不等于能执行命令。常见静默失败场景包括:
数据库处于RESTORING或
OFFLINE状态 → 查看
sys.databases的
state_desc列 登录用户无
CONNECT权限 → 在 SSMS 中右键登录名 → “属性” → “用户映射” → 勾选对应数据库并赋予
db_datareader等角色 防火墙阻止 1433 端口(Windows Server 默认关闭入站规则)→ 检查
Windows Defender 防火墙 → 高级设置 → 入站规则
一个容易被忽略的点:如果应用部署在容器或不同主机,
localhost指向的是容器/本机回环,而非宿主 SQL Server。此时必须用宿主机 IP 或配置 Docker 网络别名。
