c# - 通过 c#/Dapper 读取 MySQL 数据库时 utf8 字符不正确
问题描述
我有一个 MySQL 数据库,据我所知,它是彻头彻尾的 utf8。它是一个最初仅由 Ruby on Rails 应用程序使用的数据库,它在写入和读取 utf8 字符时没有问题。
但是,当尝试使用 Dapper 通过 ac# 应用程序读取时,我看到了很多坏字符,例如:
预期:FELIZ AÑO
实际:FELIZ AÑO
我的连接字符串如下所示:
Server=;Database=;Uid=;Pwd=;Port=;SslMode=;charset=utf8;
我尝试了几种 charset 和 utf8 大写的组合,但到目前为止都没有奏效。我在一个线程中读到,连接字符串中的字符集只影响 SQL 查询语言,所以如果这是正确的,那就是它没有帮助的原因!
还有什么我可能错过的吗?或者我可以做些什么来正确读取字符?
更新:来自 MySQL 的一些信息:
mysql> SELECT TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME, COLUMN_TYPE
-> FROM information_schema.columns
-> WHERE TABLE_NAME = 'pages'
-> AND COLUMN_NAME = 'title';
| TABLE_NAME | COLUMN_NAME | CHARACTER_SET_NAME | COLLATION_NAME | COLUMN_TYPE |
| pages | title | utf8 | utf8_general_ci | varchar(255) |
更新 2:更多信息,看来我的字符集有点混乱..
mysql> show variables like "character_set_%";
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
mysql> select collation_name from information_schema.columns where table_name = 'pages' and column_name = 'title';
+-----------------+
| collation_name |
+-----------------+
| utf8_general_ci |
+-----------------+
mysql> select title from pages where id = 3660;
+--------------------------------+
| title |
+--------------------------------+
| FELIZ AÑO |
+--------------------------------+
mysql> set character set 'latin1';
mysql> select title from pages where id = 3660;
+-----------------------------+
| title |
+-----------------------------+
| FELIZ AÑO |
+-----------------------------+
所以,数据库是latin1,默认连接是utf8,默认客户端是utf8,列是utf8。
如果我直接在 mysql 中查询该列,直到我将字符集设置为 latin1 才会出现错误。
在 C# 中使用 Execute 设置字符集并使用 ExecuteReader 读取列执行完全相同的操作仍然会产生错误字符。试图找出差异。
更新 3 - @BradleyGrainger 的屏幕截图,来自 SequelPro
解决方案
好吧,这只是 Mojibake。
HEX: 46 45 4C 49 5A 20 41 C383 E28098 4F
F E L I Z (sp) A Ã ‘ O
Mojibaked: FELIZ AÑO
Should be: FELIZ AÑO
防止它的说明在Trouble with UTF-8 characters的“Mojibake”中;我看到的不是我存储的
在阻止它之后,“修复”数据的一种方法将涉及UPDATE
更改列内容,因此:
col = CONVERT(BINARY(CONVERT(col USING latin1)) USING utf8mb4)
您可以通过以下方式看到:
SELECT CONVERT(BINARY(CONVERT('FELIZ AÑO' USING latin1)) USING utf8mb4); -- FELIZ AÑO
(请在测试环境中进行实验,而不是生产环境。)
推荐阅读
- android - geocoding_reverse 不适用于真实设备,但适用于模拟器 android studio
- javascript - 与break and catch深度互动
- python - 使用其他列的条件计算熊猫中的新列
- mysql - 使用 MySQL 过程更改表的名称
- r - 当您只有样本+可变百分比时,是否可以绘制百分比堆积条形图?
- postgresql - 创建从 mysql 到 postgresql 的等效数据库定义
- python - 二维矩阵的最小成本路径
- filtering - Serilog FilterExpression 检查 LogEvent 的所有字符串属性是否满足长度限制?
- python - 当任何行(同名)缺少数据时,删除同名行
- d3.js - 无法将大写字母添加到geojson世界地图