c# - 将 Entity Framework 与 MySQL 一起使用时,Unicode 字符将替换为基本字符

标签 c# mysql entity-framework unicode utf-8

背景

我注意到,当通过 Entity Framework 从我的 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 Entity Framework 。

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 Connection Character Sets and Collations 文档):

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

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

至于另外两个,Connector/NET Connection-String Options Reference文档状态:

CharSet , Character Set

Specifies the character set that should be used to encode all queries sent to the server. Results are still returned in the character set of the result data.

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

以下通过不在字符串前加上大写“N”显示 SQL Server 中的行为:

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 命令,以设置控制目标编码的 session 级变量:

    SET character_set_connection = utf8;
    

更多信息,请查看以下内容:

MySQL Charset/Collate

根据该页面的“utf8 Collat​​ions”部分,使用 utf8_unicode_ci 而不是 utf8_general_ci 会好得多(明确地说,这个建议与这里处理的字符转换问题无关。


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

Why do I get incorrect characters when decoding a Base64 string to NVARCHAR in SQL Server?

关于c# - 将 Entity Framework 与 MySQL 一起使用时,Unicode 字符将替换为基本字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51282125/

相关文章:

C#设置ListView的Item的Subitem的文本不显示

mysql - 将外键添加到现有表给出错误 1050 表已存在

c# - 如何将linq选择器转换为预测器

c# - WebApi 中用于响应的 DelegatingHandler

php - 如何在 MySQL 数据库中插入具有多个值的输入?

c# - Entity Framework 的投影

c# - json.net;序列化 Entity Framework 对象(循环引用错误)

entity-framework - ef5数据库第一个数据注释

c# - 在 C# 中使用本地 DTD 文件验证 XML 文件时出现问题

php - 如何使用分页将 MYSQL 中的一系列日期值显示到 php 中的表格中?