首页 > 解决方案 > 通过 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

在此处输入图像描述

标签: c#mysqlutf-8dapper

解决方案


好吧,这只是 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

(请在测试环境中进行实验,而不是生产环境。)


推荐阅读