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

时间:2018-07-11 09:39:50

标签: c# mysql entity-framework

背景

我注意到,当通过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)

有什么想法吗?感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

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文档指出:

  

字符集,字符集

     

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

需要告知与MySQL的连接,目标编码为UTF-8(这是您的MySQL列所使用的)。 MySQL当前假设您正在发送非Unicode字符串,实际上与在SQL Server中转换为VARCHAR相同,并且假定当前数据库的默认排序规则指定的代码页为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 Charset/Collate

根据该页面的“ utf8归类”部分,最好使用utf8_unicode_ci进行归类,而不要使用utf8_general_ci(要注意,此建议与字符转换问题)。


P.S。这个问题/答案对DBA.StackExhange有相应的问答:

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