【问题标题】:Entity framework with mysql database migrations fail, when creating indexes创建索引时,具有 mysql 数据库迁移的实体框架失败
【发布时间】: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。

【问题讨论】:

    标签: mysql entity-framework-6 mysql-connector


    【解决方案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
    猜你喜欢
    • 1970-01-01
    • 2014-07-08
    • 2015-09-02
    • 2018-11-17
    • 2013-04-02
    • 1970-01-01
    • 2013-05-08
    • 2021-08-25
    • 2019-03-01
    相关资源
    最近更新 更多