创建索引时,具有 mysql 数据库迁移的实体框架失败

Posted

技术标签:

【中文标题】创建索引时,具有 mysql 数据库迁移的实体框架失败【英文标题】:Entity framework with mysql database migrations fail, when creating indexes 【发布时间】:2018-10-07 10:40:56 【问题描述】:

是什么导致 mysql 中的实体框架出现此错误?我可以生成迁移脚本并连接到数据库,但它不喜欢在尝试创建索引时生成的特别“散列”的 SQL。

例子:

CREATE index  `IX_Facility_ID` on `Contact.Address` (`Facility_ID` DESC) using HASH

错误:

MySql.Data.MySqlClient.MySqlException (0x80004005):空间/全文/哈希索引和显式索引顺序的使用不正确

有没有办法解决这个问题?这是 EF 6 和最新的 mysql dll。

【问题讨论】:

【参考方案1】:

我有同样的问题,在我阅读帖子后,我决定创建一个类继承 MySqlMigrationSqlGenerator 并覆盖 protected override MigrationStatement Generate (CreateIndexOperation op),然后进行配置我添加的迁移:SetSqlGenerator ("MySql.Data.MySqlClient", new myMigrationSQLGenerator ());

这是类的代码:

public class myMigrationSQLGenerator : MySqlMigrationSqlGenerator

    private string TrimSchemaPrefix ( string table )
    
        if ( table.StartsWith ( "dbo." ) )
            return table.Replace ( "dbo.", "" );
        return table;
    

    protected override MigrationStatement Generate ( CreateIndexOperation op )
    
        var u = new MigrationStatement ( );
        string unique = ( op.IsUnique ? "UNIQUE" : "" ), columns = "";
        foreach ( var col in op.Columns )
        
            columns += ( $"`col` DESC( op.Columns.IndexOf ( col ) < op.Columns.Count - 1 ? ", " : "" )" );
        
        u.Sql = $"CREATE unique INDEX `op.Name` ON `TrimSchemaPrefix ( op.Table )` (columns) USING BTREE";
        return u;
    

这是 Migrations\Configuration.cs 上的代码:

    public Configuration ()
               
        AutomaticMigrationsEnabled = false;
        SetSqlGenerator ( "MySql.Data.MySqlClient", new myMigrationSQLGenerator ( ) );
    

这对我有用。

【讨论】:

这对我也有帮助,但我遇到了一个与我当前的文化(瑞典语)完全不同的问题,这反过来又无法解析 MySql 的版本。我得到“System.FormatException:输入字符串的格式不正确。”当 MySqlMigrationSqlGenerator 执行 ParseDouble 时。我已将其报告为错误:bugs.mysql.com/bug.php?id=92561 谢谢你们!我花了一整天的时间试图弄清楚为什么我不能在两个表之间创建外键引用。我遇到了与 Björn(瑞典计算机)完全相同的问题。我从中学到了一件事:阅读该死的异常转储,它告诉您在哪里查看! 老话题,但这个问题在 MySql Data EF 8.0.19.0 中仍然存在,所以感谢你的解决方法!【参考方案2】:

查看 MySql 源代码,您需要在索引定义上添加 this(anonymousArguments: new Type = "BTrees" ):

.Index(t => t.GroupId, anonymousArguments: new  Type = "BTrees" );

这不是修复,但目前您可以应用迁移代码。

【讨论】:

哎呀,真气人,我才浪费了半天时间试图追查这个问题。这一定是最近的问题,因为我大约一个月前使用完全相同的步骤创建了一个项目,但我没有遇到这个问题。感谢您的帮助!【参考方案3】:

我认为在 DEFAULT 生成方法之前更改线程区域设置比 henoc salinas 更好。标准实现中可能存在另一个隐藏缺陷,您每次更新 MySql 包时都需要支持这一点。

只需在通话前更改文化信息,然后在需要时恢复。

这是重做的版本:

public class CustomizedMySqlMigrationSqlGenerator : MySqlMigrationSqlGenerator

    #region Override members

    protected override MigrationStatement Generate(CreateIndexOperation op)
    
        var currentCulture = Thread.CurrentThread.CurrentCulture;
        try
        
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en");
            return base.Generate(op);
        
        finally
        
            Thread.CurrentThread.CurrentCulture = currentCulture;
        
    

    ...
    //Same for all overriden Generate() methods

    #endregion

如果您不关心区域设置持久性(代码优先模型),您也可以在 SetSqlGenerator 方法调用之前指定线程区域设置

【讨论】:

正在尝试 henoc salinas 解决方案,但未来的 MySql.Data.EF 更新似乎更安全。这工作完美。 Tks

以上是关于创建索引时,具有 mysql 数据库迁移的实体框架失败的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 实体框架:无法创建索引

在 MySQL 数据库上运行迁移时出现实体框架错误。 “空间/全文/哈希索引和显式索引顺序的错误使用”

无法使用实体框架代码优先创建具有凭据的数据库?

使用实体框架和代码优先方法创建数据库时,是不是可以从 SSMS 在数据库表上创建索引

实体框架代码优先迁移忽略 [Key] 并强制复合键

在实体框架核心中合并迁移