背景
我注意到,当通过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)
有什么想法吗?感谢您的帮助。
答案 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
-- ?
请尝试以下方法解决此问题:
第一个尝试应该是在连接字符串中添加以下内容,以将字符数据以UTF-8格式发送到MySQL(这应该只设置character_set_connection
):
CharSet=utf8;
完整连接字符串示例here
第二种尝试应该是在初始连接时发送一条SQL命令,以设置用于控制目标编码的会话级变量:
SET character_set_connection = utf8;
有关更多信息,请参见以下内容:
根据该页面的“ 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?