跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

C#中ADO.NET原生操作_C#原生数据库操作教程【详解】

SqlConnection+SqlCommand+SqlDataReader/SqlDataAdapter是最可控、最贴近SQL本质的原生方式,适合调试、学习及高性能/事务场景,但需手动管理连接、参数化查询、资源释放与超时设置。 直接说结论:用
SqlConnection
+
SqlCommand
+
SqlDataReader
或
SqlDataAdapter
是最可控、最贴近 SQL 本质的原生方式,适合调试、学习和对性能/事务有明确要求的场景;但必须手动管理连接生命周期、参数防注入、资源释放,漏掉任何一环就容易出错。 SqlConnection 连接字符串写错或没开权限,连不上怎么办 常见错误现象是抛出
SqlException
,消息里带 “A network-related or instance-specific error…” 或 “Login failed for user…”。 检查连接字符串中
Server
(实例名)是否正确,本地默认实例可写
.
或
(local)
,命名实例要带
\实例名
,比如
DESKTOP-R6BQK8P\SQLEXPRESS
Initial Catalog
(数据库名)必须已存在,不能是空库名或拼错;SQL Server Express 默认不启用 TCP/IP,需在 SQL Server 配置管理器中打开 Windows 身份验证用
Integrated Security=true
;SQL 账户登录必须确保
sa
或指定用户已启用且密码正确,且服务器身份验证模式设为“SQL Server 和 Windows 身份验证模式” 连接字符串不要硬编码在代码里,优先从
appsettings.json
(.NET Core/5+)或
App.config
读取,避免提交敏感信息 执行 INSERT/UPDATE/DELETE 时返回值总是 0 这通常不是 SQL 写错了,而是
ExecuteNonQuery()
返回的是“受影响行数”,不是“成功与否”的布尔值。如果 SQL 语法合法但没匹配到数据(比如 WHERE 条件不成立),它就真返回 0。 确认 SQL 语句本身能独立在 SSMS 中跑通,尤其是 WHERE 子句是否真能命中记录 务必使用参数化查询,别拼字符串——
"UPDATE users SET name = '" + name + "' WHERE id = " + id
是严重漏洞,也容易因单引号导致语法错误 正确写法是:
cmd.Parameters.AddWithValue("@name", name); cmd.Parameters.AddWithValue("@id", id);
,然后 SQL 字符串里写
UPDATE users SET name = @name WHERE id = @id
如果需要获取刚插入的自增 ID,别用
SELECT @@IDENTITY
,改用
SELECT SCOPE_IDENTITY()
并配合
ExecuteScalar()
SqlDataReader 读完不 Close,程序卡死或内存暴涨
SqlDataReader
是连接态、只进、只读游标,它会一直占用底层连接,直到显式关闭或被 dispose。忘记关,后续操作就会阻塞在
Open()
上,或者引发“超时”“连接池已满”等错误。 C知道 CSDN推出的一款AI技术问答工具 下载 永远用
using
包裹:
using (var reader = cmd.ExecuteReader()) { while (reader.Read()) { ... } }
—— 这能保证即使异常也会释放资源 不要在
while (reader.Read())
循环里调
reader.Close()
,也不要在循环外手动
Dispose()
,
using
已涵盖 如果只是查单行,用
ExecuteScalar()
更轻量;如果要加载整张表到内存做筛选/绑定,用
SqlDataAdapter.Fill(DataTable)
更合适 注意:DataReader 不支持多次遍历,读完就没了;想重复用,得重新执行命令或换用 DataTable 事务里多个 SqlCommand 共享同一个 SqlConnection 却报错 典型错误是
SqlConnection does not support parallel transactions
或 “There is already an open DataReader associated with this Connection”。根本原因是:一个
SqlConnection
同一时刻只能有一个活跃的命令(包括 Reader、ExecuteNonQuery 等)。 事务内所有命令必须复用同一个
SqlConnection
实例,并显式传入
SqlTransaction
对象给每个
SqlCommand
的
Transaction
属性 不能在一个连接上一边
ExecuteReader()
,一边又
ExecuteNonQuery()
—— 必须等 Reader 关闭后才能执行下一个命令 如果事务跨多个方法,把
SqlConnection
和
SqlTransaction
当作参数传进去,而不是在每个方法里 new 新连接 别依赖连接池自动回收:事务未
Commit()
或
Rollback()
就丢弃连接对象,连接池会把它标记为“不可重用”,造成连接泄漏 最常被忽略的一点:原生 ADO.NET 没有自动重试、没有连接健康检查、没有命令超时自动取消(除非显式设
CommandTimeout
)。一旦网络抖动或 SQL 长时间卡住,整个线程就挂在那里。生产环境务必设
Connection Timeout=30
和
Command Timeout=60
,并考虑封装一层带重试逻辑的执行器。

相关文章