实体框架核心的MySQL整理问题

时间:2018-05-24 11:08:05

标签: c# mysql asp.net-core entity-framework-core

我的asp.net核心Web应用程序正在点击MySQL数据库。我生成迁移和更新数据库,然后我看到表的排序规则在不同的机器上是不同的。在我的机器上 latin1 - 默认排序规则,在另一台计算机上,它是 utf8 - 默认排序规则

因此,由于这种行为,我在将日语或其他语言工作(例如日本语,EspañolMéxico或简体中文)插入到具有varchar(64)列的表中时遇到异常。它在另一台机器上运行正常,该机器上有 utf8 - 默认排序规则

EF核心版本: 2.0.1

MySql: 5.7.22 **

这是EF核心问题吗?或者是否有任何解决方法来使用正确的排序规则或编码生成数据库?

2 个答案:

答案 0 :(得分:1)

这不是EF Core问题,如果您在MySql中配置了默认排序规则,那么将由MySql选择。因此整理是数据库系统配置的事情。可能您必须更改计算机上的默认排序规则。

其他选项是在迁移中创建表语句后添加:

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

答案 1 :(得分:1)

手动将每一列配置为特定的 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;
        }
    }
}

设置每个属性的字符集

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

通过查询列排序规则设置检查结果

> 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               |
+-------------+--------------------+--------------------+

带有 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>

注意以下可以设置 CharSet,但 Collation 固定为 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()
            );