sqlsugarclient必须单例或scoped注册,禁止方法内new、using或手动事务;queryable需.tolist()等触发执行;分页须用.topagelist();事务须用ado.usetran();ado操作不可跨client混用。

SqlSugar 不是“开箱即用”的 ORM,直接照抄示例代码大概率连连接都打不开——核心问题出在初始化时机、作用域管理、以及 Ado.UseConnection 这类底层 API 的误用上。
SqlSugarClient 初始化必须单例或作用域内复用,不能每次查询 new 一个
常见错误是把 new SqlSugarClient(...) 写在方法里,导致连接池失控、事务失效、内存泄漏。SqlSugar 的设计前提就是 SqlSugarClient 是线程安全的、可长期持有的实例。
- Web 项目(如 ASP.NET Core)务必注册为
Scoped或Singleton,推荐Scoped(配合 DI 自动释放) - 控制台或 WinForms 项目,应定义静态字段或使用
Lazy<sqlsugarclient></sqlsugarclient>延迟初始化 - 绝对不要在
using (var db = new SqlSugarClient(...))中使用——SqlSugarClient不实现IDisposable,且内部连接由自己管理 - 若需多数据库,用
Ado.UseConnection切换连接字符串,而不是 new 多个 client
Queryable 查询时加 .ToList() 或 .First() 才真正执行 SQL
SqlSugar 的 Queryable<t></t> 是延迟执行的,看起来像 LINQ to Objects,但底层是构建 SQL 表达式树。不触发终结操作,SQL 根本不会发往数据库。
- 写
db.Queryable<user>().Where(x => x.Id > 100)</user>只是拼 SQL,没查库 - 必须调用
.ToList()、.First()、.Count()、.Any()等才会执行 - 调试时想看生成的 SQL?用
.ToSql()(返回(sql, parameters)元组),不是.ToString() - 注意
.Ado.UseConnection仅对当前查询生效,不影响后续 Queryable 链式调用
事务必须用 Ado.UseTran,不能靠 BeginTransaction + Commit
SqlSugar 的事务控制和 ADO.NET 原生方式不同:它要求所有参与事务的操作都走同一个 Ado 实例,而这个实例由 UseTran 提供。手动调用 BeginTransaction 会脱离 SqlSugar 的上下文管理。
- 正确姿势:
db.Ado.UseTran(() => { db.Insert(...); db.Update(...); }); - 错误姿势:
var tran = db.Ado.BeginTransaction(); ... tran.Commit();—— 此时Insert和Update默认走新连接,不进事务 - 跨多个
SqlSugarClient实例无法共用事务;必须确保所有操作都在UseTran回调内完成 - 若需嵌套事务(SavePoint),用
db.Ado.UseTran(() => { ... }, true)启用支持
分页必须用 .ToPageList(pageIndex, pageSize),别手写 OFFSET FETCH
SqlSugar 分页自动适配不同数据库(SQL Server 用 OFFSET FETCH,MySQL 用 LIMIT,Oracle 用 ROWNUM),但前提是用它内置方法。手写 SQL 或用 Skip().Take() 会丢失分页语义、性能崩坏、甚至报错。
-
db.Queryable<user>().Where(x => x.Status == 1).ToPageList(2, 20)</user>→ 正确 -
db.Queryable<user>().Where(...).Skip(20).Take(20)</user>→ 错!全表加载后内存分页,大数据量直接 OOM -
ToPageList返回(List<t>, total)</t>元组,total 是总条数(含 COUNT(*) 优化) - 若只需数据不要总数,用
ToPageListAsync+IsAutoCount = false配置提升性能
最常被忽略的是:SqlSugar 的 Ado 子系统(Ado.UseConnection / Ado.UseTran)和主 SqlSugarClient 是强耦合的,混用不同 client 的 Ado 会导致连接错乱、事务丢失、参数绑定失败。别图省事把 client 当工具类传参,该用依赖注入就注入,该用 Scoped 就别 Transient。










