简体   繁体   English

Entity Framework Core 的 MySQL 整理问题

[英]MySQL collation issue with Entity Framework Core

My asp.net core web application is hitting is MySQL database.我的 asp.net 核心 Web 应用程序命中的是 MySQL 数据库。 I generate migration and update database, then I see the collation of table which is different on different machines.我生成迁移和更新数据库,然后我看到不同机器上不同的表的排序规则。 On my machine its latin1 - default collation and on a different machine, it is utf8 - default collation .在我的机器上,它是latin1 - 默认排序规则,而在另一台机器上,它是utf8 - 默认排序规则

So due to this behavior, I'm getting an exception while inserting Japanese or some other language work like 日本語, Español México or 简体中文 into a table which has a varchar(64) column.因此,由于这种行为,我在将日语或其他语言作品(如日本语、Español México 或简体中文)插入具有 varchar(64) 列的表时遇到异常。 It works fine on another machine which has utf8 - default collation on this table.它在另一台具有utf8 的机器上运行良好-此表上的默认排序规则

EF Core Version: 2.0.1 EF 核心版本: 2.0.1

MySql: 5.7.22** MySql: 5.7.22**

Is this EF Core issue?这是 EF Core 问题吗? Or is there any workaround to generate the database with the proper collation or encoding?或者是否有任何解决方法可以使用正确的排序规则或编码生成数据库?

It is not EF Core issue, if you have default collation configured in your MySql then that will be picked by MySql.这不是 EF Core 问题,如果您在 MySql 中配置了默认排序规则,则 MySql 将选择该排序规则。 So collation is database system configuration thing.所以整理是数据库系统配置的事情。 Probably you have to change your default collation on your machine.可能您必须更改机器上的默认排序规则。

Other option is to add after creating table statement in migration:其他选项是在迁移中创建表语句后添加:

Sql('alter table <some_table> convert to character set utf8 collate utf8_unicode_ci');

Configure every column manually to a specific CharSet and Collation, In case you cannot change server/schema default CharSet or Collation (you are not the Server administrator)手动将每列配置为特定的 CharSet 和 Collat​​ion,以防您无法更改服务器/模式默认 CharSet 或 Collat​​ion(您不是服务器管理员)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Pomelo.EntityFrameworkCore.MySql.Extensions;
using Pomelo.EntityFrameworkCore.MySql.Infrastructure;

namespace Data
{
    public static class Extensions
    {
        internal static PropertyBuilder<string>  TextField(this PropertyBuilder<string> string_column, int max_length)
        {
            string_column.TextField(CharSet.Utf8Mb4, "utf8mb4_unicode_ci", max_length);
            return string_column;
        }
        internal static PropertyBuilder<string>  TextField(this PropertyBuilder<string> string_column, CharSet char_set, string collation, int max_length)
        {
            string_column.HasColumnType($"VARCHAR({max_length}) CHARACTER SET {char_set} COLLATE {collation}");
            return string_column;
        }
    }
}

Set character set of each property设置每个属性的字符集

        protected override void OnModelCreating(ModelBuilder builder)
        {
            ...
            builder.Entity<TABLE>().Property(t => t.Name).TextField(1024);
            ...
        }

Check the result by query column collation settings通过查询列排序规则设置检查结果

> mysql.exe --login-path=mysql1 --database=test1 -e "select column_name, character_set_name, collation_name from information_schema.columns where table_name = 'TABLE';"

+-------------+--------------------+--------------------+
| column_name | character_set_name | collation_name     |
+-------------+--------------------+--------------------+
| Id          | NULL               | NULL               |
| Name        | utf8mb4            | utf8mb4_unicode_ci |
| CreatedTime | NULL               | NULL               |
| UpdatedTime | NULL               | NULL               |
+-------------+--------------------+--------------------+

My Entity Framework Project lib with MySQL 5.7.21 .我的实体框架项目库与 MySQL 5.7.21

 <ItemGroup>
    ...
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.1">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="5.0.0-alpha.2" />
  </ItemGroup>

Noted the following can set CharSet but Collation is fixed to utf8mb4_general_ci .注意以下可以设置CharSetCollation固定为utf8mb4_general_ci

            services.AddPooledDbContextFactory<ApplicationDbContext>(
                options => options
                    .UseMySql(
                        Configuration["ConnectionString"],
                        new MySqlServerVersion(new Version(5, 7, 21)),
                        mySqlOptions =>
                        {                          
                            mySqlOptions
                               .CharSetBehavior(CharSetBehavior.AppendToAllColumns);
                            mySqlOptions.CharSet(CharSet.Utf8Mb4);
                        })
                    .EnableSensitiveDataLogging()
                    .EnableDetailedErrors()
            );

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM