C#如何使用SqlSugar_C#国产强类型ORM快速入门【核心】
C# 使用 SqlSugar 必须避开的几个“静默坑” SqlSugar 不是那种需要花大量时间配置上下文的ORM,它主打快速落地——配对连接字符串和实体,Queryable 和 Updateable 就能直接跑起来,不用建上下文、不用写迁移脚本、也不用配置映射文件。但快速不代表无脑:有几个关键点一
C# 使用 SqlSugar 必须避开的几个“静默坑”
SqlSugar 不是那种需要花大量时间配置上下文的ORM,它主打快速落地——配对连接字符串和实体,Queryable 和 Updateable 就能直接跑起来,不用建上下文、不用写迁移脚本、也不用配置映射文件。但快速不代表无脑:有几个关键点一旦忽略,就会在运行时出现静默失败,让你查半天都不知道问题出在哪。
先说几个核心判断:DbType必须显式指定,不能靠连接字符串自动猜;实体类最好用特性标注清楚,否则表名主键对不上就查不出数据;null判断必须用 == null 或 != null,其他写法可能生成错误的SQL;事务必须通过 Ado.UseTran 统一管理,别以为自己调用 BeginTransaction() 就万事大吉。

怎么配 ConnectionConfig 才不报 DbType 不匹配
最常见的错误是配完连接后查不出数据,而且系统不抛任何异常。你打开数据库一看,SQL语句是有的,但结果集永远是空。原因很简单:DbType枚举没有显式指定,或者指定错了。
- SqlSugar 不会根据连接字符串里的关键字(比如MySQL的
Server=localhost)自动推断数据库类型,你必须手写DbType.MySql、DbType.SqlServer等枚举值。 - 枚举值不能写错:SQL Server用
SqlServer,MySQL用MySql,SQLite用Sqlite,PostgreSQL用PostgreSQL。拼错或用错,比如MySQL连接串配了DbType.SqlServer,Queryable可能返回空集合且不报错——这就是静默失败。 - 国产数据库(达梦、人大金仓)需要额外安装驱动,并且确认
DbType是否支持。部分版本只能用DbType.Custom配合自定义适配器,否则也会静默失败。
所以,检查一下你的 ConnectionConfig 中 DbType 和 ConnectionString 是不是严格匹配。这是最基础的,但也是最容易翻车的地方。
实体类不加特性也能查,但为什么一定要加 SugarTable 和 SugarColumn
不加特性时,SqlSugar 默认用类名当表名、属性名当字段名。表面看省事,实际漏洞不少:
- 如果数据库表名是
user_info(含下划线),类名写成UserInfo,默认转换会变成userinfo,查不到数据。 - 主键字段不叫
Id或ID,比如叫user_id,不标注[SugarColumn(IsPrimaryKey = true)]就无法使用InSingle方法获取单条记录。 - 字段长度、是否为空、默认值等约束全靠运行时推断,
CodeFirst.InitTables建表时可能把字符串全建成nvarchar(50),跟你的实际需求不符。 IsIdentity = true必须显式标注,否则在事务中插入后拿不到自增ID。
建议:哪怕只是小项目,也花两分钟把表名和主键特性加上。这点耐心,能省掉后面大量的排查时间。
Queryable 写 WHERE 条件时,null 判断为什么总失效
典型现象:代码写 .Where(x => x.Name != null),生成 SQL 却是 WHERE Name NULL(永远为 false)。这其实是 SqlSugar 表达式树解析的一个特殊限制:
- 必须用
== null或!= null这种直接比较,不要用object.Equals(x.Name, null)或string.IsNullOrEmpty(x.Name),后者不会被识别为SQL的IS NULL/IS NOT NULL。 - 字符串判空需要写两步:
.Where(x => x.Name != null && x.Name != ""),不支持string.IsNullOrWhiteSpace。 - 可空类型(如
int?)用.Where(x => x.Status.HasValue)是安全的。旧版(v5.1.4之前)用x.Status != null可能生成错误的SQL,建议升级。 - 调试利器:打开
Aop.OnLogExecuting,看实际发出的 SQL 是否包含IS NULL。如果不是,说明表达式没被正确识别,赶紧换写法。
事务里用 Updateable 更新失败却不回滚?
根本原因在于 SqlSugar 的事务控制粒度在 SqlSugarScope 层,而不是每个 Updateable 自动加入当前事务。很多人只调了 BeginTransaction(),但那个只影响 ADO.NET 层,Updateable 会新建连接,导致事务失效。
- 必须用
Ado.UseTran显式开启事务,这是正确用法:
db.Ado.UseTran(() => {
db.Updateable(entity).ExecuteCommand();
db.Insertable(other).ExecuteCommand();
});
- 如果混用
Ado原生操作和Updateable,必须全部放在同一个UseTran闭包内。跨闭包的调用不共享事务上下文。 IsAutoCloseConnection = true在事务中必须设为false,否则每次ExecuteCommand后连接会被关闭,事务自然中断。
最容易被忽略的一点:SqlSugar 的强类型不是靠编译期检查,而是靠运行时解析表达式树。所有 Queryable / Updateable 的 lambda 参数,必须是实体的真实属性路径(比如 x.CreateTime),不能是计算属性、方法调用或局部变量引用,否则静默降级为内存查询或直接抛出 NotSupportedException。这一点在做复杂条件过滤时尤其要小心。


































