Dapper常见报错集中在字段映射不一致、参数化查询错误、空值类型转换异常、连接未释放或事务未提交四类。需通过Column特性、统一命名、可空类型、using包裹连接等方式解决。

字段映射不一致导致查询失败
实体类属性名和数据库字段名不匹配是最常见的报错原因之一。比如数据库字段是 user_name,而 C# 类里写的是 UserName,Dapper 默认不会自动转换下划线命名。
解决方法:
- 在属性上加 [Column("user_name")] 特性,显式指定映射
- 启用严格映射模式:在启动时调用 Dapper.DefaultTypeMap = new CustomPropertyTypeMap(...) 或使用第三方库如 Dapper.FluentMap
- 统一命名风格,推荐数据库用 snake_case,C# 类用 PascalCase,并配合 Dapper 的 SqlMapper.AddTypeMap 做全局小写转驼峰
- 检查是否遗漏了 get/set 访问器,只读属性无法被 Dapper 赋值
参数化查询出错:“必须声明标量变量 @xxx”
这个错误通常不是 SQL 写错了,而是你用了字符串拼接代替参数化,或者参数对象结构与 SQL 中的参数名对不上。
常见情况:
- SQL 里写了 @Name,但传入的是 new { name = "xxx" }(大小写不一致)
- 使用了匿名对象,但字段名拼错,比如 new { UserName = "a" } 却在 SQL 中写 @username
- 在批量操作中误把列表直接当参数传,例如 .Execute(sql, userList) —— 应该用 .Execute(sql, userList.First()) 或改用 ExecuteAsync + 批量语法
空值引发的类型转换异常
数据库字段允许 NULL,但 C# 属性是 int、DateTime 这类非空值类型,查到 NULL 时就会抛“指定的转换无效”。
应对方式:
- 把属性改为可空类型,如 int?、DateTime?
- 在 SQL 中用 ISNULL(Price, 0) 或 COALESCE(Price, 0) 提前处理空值
- 对 Oracle 等数据库,时间差计算等表达式容易返回 NULL,建议在 SELECT 中包裹 NVL(..., 0) 或 ROUND(..., 2) 防止精度问题
连接未释放或事务未提交
Dapper 不管理连接生命周期,它只负责执行 SQL。如果忘了 using 或没调 conn.Open(),运行时可能卡住、超时或报“连接已关闭”。
稳妥写法:
- 始终用 using (var conn = new SqlConnection(connStr)) 包裹
- 手动开启事务时,务必配对 BeginTransaction 和 Commit/Dispose
- 避免跨方法传递未打开的连接对象;连接打开后才能 Query/Execute
- 达梦、Oracle 等国产库需确认驱动版本与 .NET 框架匹配(如达梦 net45 对应 .NET Framework 4.8)
基本上就这些。多数 Dapper 报错都落在映射、参数、空值、连接四块,理清这几点,90% 的问题能快速定位。










