草庐IT

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

coder 2023-10-18 原文

背景

我注意到,当通过 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# - 将 Entity Framework 与 MySQL 一起使用时,Unicode 字符将替换为基本字符的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  3. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  4. ruby-on-rails - unicode 字符串的长度 - 2

    在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  7. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  8. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  9. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  10. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

随机推荐