7

问题的根本:

双关语意。

问题始于一个非常古老的 dBase 数据库,其中文本信息直接编码为DOS Cyrillic (CP-866),因为这还不够,所以每天晚上它也会被传输到 MySQL 数据库,我可以访问它.

我已经安装了 MySQL Providers 并使用 Entity Framework 连接到数据库,这是我的主要数据访问方法,然后出于实验原因使用纯 ADO.NET 也是如此。

在我尝试将所谓的CP-866值从数据库转换为UTF-8之前,一切都比预期的要好,如下所示:

var cp866 = Encoding.GetEncoding(866);
var utf8 = Encoding.UTF8;

string source = "some unreadable set of characters from the database";
byte[] cp866bytes = cp866.GetBytes(source);
byte[] utf8bytes = Encoding.Convert(cp866, utf8, cp866bytes);
string result = utf8.GetString(utf8bytes);

我用 EntityFramework 读过一次,用 ADO.NET 读过一次,结果相同。

由于当时未知和现在鲜为人知的原因,它没有用。在阅读了一些关于编码和字符串值的重要文章后,我确定由于字符串变量本身的性质,不可能将这种转换应用于数据库中 varchar 字段的字符串等效项。

几次键盘敲击之后,我终于通过使用 ADO.NET MySQL Provider 并通过将CONVERT(varcharColumn, Binary)添加到我正在测试的列来自定义我的查询来实现它。

从那时起,我使用上面的代码,唯一的区别是我已经从转换中获得了 cp866 字节数组。我最初打算做类似的事情,但 MySQL 提供程序无法直接从 varchar 字段读取字节,我也没有找到使用 Entity Framework 的方法。

是的,它有效,但即使对于我没有经验的自己来说,它也感觉不对。



问题:

1:我可以指定实体框架应该如何选择特定的字段吗?

我想以某种方式解释我心爱的 ORM,它应该在读取过程中将特定的 varchar 字段转换为二进制,而根本不返回字符串表示,因为它搞砸了一切。

2:有没有办法让 ADO.NET MySQL 提供程序获取 varchar 字段的字节,而无需先将其作为字符串拉出?

GetBytes 方法在与 varchar 一起使用时会引发异常,并且 MySQL 版本中缺少通常存在于 ADO.NET 提供程序中的 GetSqlBytes 方法。我真的不想在我需要正确阅读的每个字段上编写二进制转换。

3:额外问题:是否可以像我一样将 CP-866 编码的 varchar 字段读取为字符串,但这次正确地将编码更改为 UTF-8?

经过今天的阅读,我的脑海中仍然有很多关于编码主题的混乱。我仍然相信我可能遗漏了一些东西,并且可以从 cp-866 编码的 varchar 字段中读取字符串,例如:

string cp866EncodedValue = "Œ€„‹… Œ‹€„…Ž‚€ Šš…‚€"; //actual copy-pasted value

..然后将其转换为 UTF-8,同时记住数据库中的字段是用 CP-866 编码的。从我读过的内容来看,只要它在一个字符串中,它就是 unicode 并且字符串是不可变的。我已经尝试过获取它的 byre 数组表示,将其更改为 cp866,然后更改为 utf8,我尝试使用它,因为它本身就是 cp866,但没有成功。

4

1 回答 1

0

首先,我会检查您的数据库和/或有问题的表上的当前编码。

@eggyal 指向链接,其中有这些用于设置某些变量的命令:

SET character_set_client = charset_name;
SET character_set_results = charset_name;
SET character_set_connection = charset_name;

要检查这些,请使用以下内容:

SHOW VARIABLES LIKE 'character_set_client';
SHOW VARIABLES LIKE 'character_set_results';
SHOW VARIABLES LIKE 'character_set_connection';

然后对于数据库的默认字符编码,使用:

SHOW CREATE DATABASE databaseName;

然后对于该特定表,请检查:

show create table TABLE_IN_QUESTION;

在这些之后,您知道,哪些是您的数据库和/或表的确切编码。


我解决已发现问题的解决方案只是指向一个有趣来源的链接。请看一下这篇文章是否有相关内容要讲述:

http://nicj.net/mysql-converting-an-incorrect-latin1-column-to-utf8/


PS。的,我可以阅读 url,它说明转换 latin1 -> utf8,但据我了解,相同的提示也适用于其他字符编码对。

于 2013-06-13T20:50:06.670 回答