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

2023-12-04

背景

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

所采取的行动

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

modelBuilder.Properties<string>().Configure(x => { x.HasColumnType("NVARCHAR"); x.IsUnicode(true); });

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

AlterColumn("dbo.Item", "Name", c => c.String(maxLength: 800, storeType: "nvarchar"));

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

持续存在的问题

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

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

其他信息

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

dbContext.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);

看似没问题的SQL。

SET SESSION sql_mode='ANSI';INSERT INTO `Item`(
`Name`, 
`Owner_Id`) VALUES (
@gp1, 
@gp2);

-- @gp1: 'The_α_1' (Type = String, IsNullable = false, Size = 7)

-- @gp2: '7a897e05-cc87-410b-bc80-70c75abae95b' (Type = String, IsNullable = false, Size = 36)

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


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

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

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

至于另外两个,则连接器/NET 连接字符串选项参考文档指出:

字符集,字符集

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

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

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

SELECT 'α'; -- Database's default Collation = Latin1_General_100_CI_AS_SC
-- a

SELECT 'α'; -- Database's default Collation = Hebrew_100_BIN2
-- ?

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

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

    CharSet=utf8;
    

    完整连接字符串示例here

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

    SET character_set_connection = utf8;
    

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

MySQL 字符集/整理

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


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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐