Dapper 不负责字符编码转换,乱码源于数据库连接、服务端、客户端及字段编码不一致;需统一配置连接字符串、库表字符集、字段类型,并在必要时手动转码。

Dapper 本身不负责字符编码转换,它只是轻量级的 ORM 映射器,所有编码行为取决于底层数据库连接(如 sqlConnection、mysqlConnection 或 Sybase 的 ADO.net 驱动)以及数据库服务端、客户端、表字段三者的字符集配置是否一致。乱码问题往往出现在“读取时解码错误”或“写入时编码丢失”,不是 Dapper 的 bug,而是链路中某处编码断层。
确认并统一数据库连接字符串编码参数
连接字符串是第一道关卡,必须显式声明字符集:
- MySQL:加上
charset=utf8mb4;(推荐),避免用utf8(MySQL 中实际是 utf8mb3,不支持 emoji 和部分生僻汉字) - Sybase ASE:加上
Charset=cp850;或Charset=gb2312;(取决于服务器syscharsets实际配置,可用isql查询确认) - SQL Server:默认 UTF-16 支持良好,但若连的是老版本或用了
varchar字段,需确保数据库排序规则含_UTF8(如Chinese_PRC_CI_AS_UTF8)
检查数据库对象本身的字符集定义
即使连接正确,如果库/表/列没设对编码,Dapper 读出来的仍是乱码:
- MySQL:建库建表时指定
default CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci - Sybase:用
sp_helpsort查看服务器默认排序,用alter database ... with charset=gb2312(需 dba 权限) - 字段类型优先用
nvarchar(SQL Server)、TEXT或MEDIUMTEXT(MySQL)等 Unicode 类型,避免varchar+ 非 UTF 编码组合
针对 Sybase cp850 环境的手动转码(常见于旧系统)
当数据库强制使用 cp850(如 windows 拉丁字符集),而 .NET 默认无法正确解析中文时,可在查询后立即做一次编码转换:
public static string CP850ToGB2312(string str) { if (string.IsNullOrEmpty(str)) return str; try { var cp850 = Encoding.GetEncoding(850); var gb2312 = Encoding.GetEncoding("gb2312"); byte[] bytes = cp850.GetBytes(str); return gb2312.GetString(bytes); } catch { return str; } }
然后在 Dapper 查询后调用:
var result = conn.Query("SELECT DEPT_NAME FROM ...").ToList(); foreach (var r in result) r.DEPT_NAME = CP850ToGB2312(r.DEPT_NAME);
MySQL jsON 字段中文乱码的特殊处理
MySQL 的 json 类型字段在 Dapper 查询时容易因驱动未透传编码导致中文变 ???:
- 插入前对 JSON 中文做 URL 编码:
HttpUtility.UrlEncode("张三") - 查出后再
HttpUtility.UrlDecode还原 - 更优方案:改用
LONGTEXT存储 JSON 字符串,并确保该字段为utf8mb4编码
基本上就这些。关键不是“Dapper 怎么设编码”,而是让整个数据链路——从建库、建表、连库、读写——都落在同一套编码逻辑里。中间任何一环掉队,Dapper 就只能忠实地把乱码映射给你。