C# Dapper常见错误及解决方法 Dapper疑难杂症排查

来源:这里教程网 时间:2026-02-21 17:35:33 作者:

字段映射不一致导致查询失败

实体类属性名和数据库字段名不匹配是最常见的报错原因之一。比如数据库字段是 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# 属性是 intDateTime 这类非空值类型,查到 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)) 包裹 手动开启事务时,务必配对 BeginTransactionCommit/Dispose 避免跨方法传递未打开的连接对象;连接打开后才能 Query/Execute 达梦、Oracle 等国产库需确认驱动版本与 .NET 框架匹配(如达梦 net45 对应 .NET Framework 4.8)

基本上就这些。多数 Dapper 报错都落在映射、参数、空值、连接四块,理清这几点,90% 的问题能快速定位。

相关推荐