将实体框架与 MySQL 一起使用时,Unicode 字符将替换为基本字符

Gee*_*_SO 3 c# mysql unicode entity-framework utf-8

背景

\n\n

我注意到,当通过实体框架从我的 MVC 网站保存数据时,如果我有类似希腊语“\xce\xb1”的内容,它将被转换为“a”。

\n\n

所采取的行动

\n\n

我在数据库上下文中覆盖OnModelCreating并添加了以下代码。

\n\n
modelBuilder.Properties<string>().Configure(x => { x.HasColumnType("NVARCHAR"); x.IsUnicode(true); });\n
Run Code Online (Sandbox Code Playgroud)\n\n

这最初看起来很有希望,因为新生成的迁移具有这种结构。

\n\n
AlterColumn("dbo.Item", "Name", c => c.String(maxLength: 800, storeType: "nvarchar"));\n
Run Code Online (Sandbox Code Playgroud)\n\n

运行迁移后,我看到相关列有排序规则utf8_general_ci

\n\n

持续存在的问题

\n\n

通过我的应用程序保存数据时,这没有任何改变。当从网站传递希腊字符时,它仍然降级为基本等效字符。

\n\n

然而,如果我尝试直接通过 MySQL Workbench 添加这些字母,它会很好地存储它们,并且网站在检索数据时将正确显示。

\n\n

其他信息

\n\n

使用下面的数据库日志记录代码,我能够看到正在使用的 SQL 实体框架。

\n\n
dbContext.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);\n
Run Code Online (Sandbox Code Playgroud)\n\n

看似没问题的SQL。

\n\n
SET SESSION sql_mode=\'ANSI\';INSERT INTO `Item`(\n`Name`, \n`Owner_Id`) VALUES (\n@gp1, \n@gp2);\n\n-- @gp1: \'The_\xce\xb1_1\' (Type = String, IsNullable = false, Size = 7)\n\n-- @gp2: \'7a897e05-cc87-410b-bc80-70c75abae95b\' (Type = String, IsNullable = false, Size = 36)\n
Run Code Online (Sandbox Code Playgroud)\n\n

有任何想法吗?谢谢你的帮助。

\n

Sol*_*zky 6

MySQL 允许配置客户端-服务器通信的多个方面(根据10.4 连接字符集和排序规则文档):

\n\n
    \n
  • 源(即客户端)编码:character_set_client
  • \n
  • 目的地(即服务器)编码:character_set_connection
  • \n
  • 返回的数据和元数据:character_set_results
  • \n
\n\n

我猜测,假设来自 Microsoft 技术的源编码是 UTF-16 Little Endian。

\n\n

至于其他两个,Connector/NET Connection-String Options Reference文档指出:

\n\n
\n

字符集,字符集

\n\n

指定应用于对发送到服务器的所有查询进行编码的字符集。结果仍以结果数据的字符集返回。

\n
\n\n

需要告知与 MySQL 的连接目标编码是 UTF-8(这是您的 MySQL 列正在使用的编码)。MySQL 当前假设您正在发送非 Unicode 字符串,实际上与 SQL Server 中的转换相同VARCHAR,假设当前数据库的默认排序规则指定的代码页为 1252(Windows 代码页 1252 通常称为作为“ ANSI ”,即使这在技术上是一个不准确的名称)。

\n\n

下面显示了 SQL Server 中不使用大写“N”作为字符串前缀的行为:

\n\n
SELECT \'\xce\xb1\'; -- Database\'s default Collation = Latin1_General_100_CI_AS_SC\n-- a\n\nSELECT \'\xce\xb1\'; -- Database\'s default Collation = Hebrew_100_BIN2\n-- ?\n
Run Code Online (Sandbox Code Playgroud)\n\n

请尝试以下方法来解决此问题:

\n\n
    \n
  1. 第一次尝试应该是将以下内容添加到连接字符串中,以将字符数据作为 UTF-8 发送到 MySQL(这应该只是设置character_set_connection):

    \n\n
    CharSet=utf8;\n
    Run Code Online (Sandbox Code Playgroud)\n\n

    完整的连接字符串示例在这里

  2. \n
  3. 第二次尝试应该是在初始连接时发送 SQL 命令,以设置控制目标编码的会话级变量:

    \n\n
    SET character_set_connection = utf8;\n
    Run Code Online (Sandbox Code Playgroud)
  4. \n
\n\n

欲了解更多信息,请参阅以下内容:

\n\n

MySQL 字符集/整理

\n\n

根据该页面的“utf8 Collat​​ions”部分,使用utf8_unicode_ci排序规则而不是更好utf8_general_ci(要明确的是,此建议与此处处理的字符转换问题无关)。

\n\n
\n\n

PS 这个问题/答案在 DBA.StackExhange 上有一个配套的问答:

\n\n

在 SQL Server 中将 Base64 字符串解码为 NVARCHAR 时,为什么会得到不正确的字符?

\n