c# - 带有 MySql 和迁移的 Entity Framework 因 "max key length is 767 bytes"而失败

标签 c# mysql entity-framework

[编辑]这个问题解决了!请参阅帖子末尾的说明。

[编辑 2] 好的,这个线程很旧,新版本的 MySQL 连接器已经用 MySQL EF 解析器处理了这个问题。在这个线程上寻找@KingPong 的答案。不过我还没有测试过。

我正在尝试将 MySql 和 EntityFramework 与 Migrations 一起使用,但似乎有问题。

当我在包管理器控制台中输入 Update-Database -Verbose 时,EF 执行一些查询,这些查询将“镜像”我的模型类,一切都很完美,但随后 EF 尝试执行此查询:

create table `__MigrationHistory` 
(
  `MigrationId` varchar(150)  not null 
  ,`ContextKey` varchar(300)  not null 
  ,`Model` longblob not null 
  ,`ProductVersion` varchar(32)  not null
  ,primary key ( `MigrationId`,`ContextKey`) 
 ) engine=InnoDb auto_increment=0

结果是:Specified key was too long;最大 key 长度为 767 字节

我尝试将我的数据库排序规则更改为 utf-8,但还是一样。也许 key 长度是 450 个字符,进行 UTF-8 数学运算(我可能错了),我认为它试图创建一个大约 1800 字节长度的 key 。

由于我是 EF 新手,所以我遵循了一些教程,他们告诉我这样做:

    public Configuration()
    {
        AutomaticMigrationsEnabled = false;

        SetSqlGenerator("MySql.Data.MySqlClient", new MySql.Data.Entity.MySqlMigrationSqlGenerator());
    }

也许这个 SQL 生成器做错了,或者 EF 本身要求生成器生成一个最长 767 字节的 key 。

我该如何解决这个问题,避免这个问题并让它与 MySql 一起工作?

[编辑] 好的,这个问题解决了。你必须告诉 EF 它必须改变它生成 __MigrationHistory 表的方式。

我做了什么: 首先,使用以下内容创建一个名为 MySqlHistoryContext.cs (或任何您想要的)的文件:

...
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Migrations.History;


namespace [YOUR NAMESPACE].Migrations //you can put any namespace here, but be sure you will put the corret using statement in the next file. Just create a new class :D
{
    public class MySqlHistoryContext : HistoryContext
    {

        public MySqlHistoryContext(DbConnection connection, string defaultSchema):base(connection,defaultSchema)
        {

        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<HistoryRow>().Property(h => h.MigrationId).HasMaxLength(100).IsRequired();
            modelBuilder.Entity<HistoryRow>().Property(h => h.ContextKey).HasMaxLength(200).IsRequired(); 
        }
    }
}

您的 Migrations 文件夹中可能有一个名为 Configuration.cs 的文件。如果是,请进行必要的调整,否则创建一个新文件。实际上,如果您没有此文件,您将无法遇到此错误,因为 EF 会在您 Add-Migration [name] 时自动创建它。

namespace [YOUR NAMESPACE].Migrations
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Migrations;
    using System.Linq;

    internal sealed class Configuration : DbMigrationsConfiguration<CodeFirstMySql.Models.Context>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = false;

            SetSqlGenerator("MySql.Data.MySqlClient", new MySql.Data.Entity.MySqlMigrationSqlGenerator()); //it will generate MySql commands instead of SqlServer commands.

            SetHistoryContextFactory("MySql.Data.MySqlClient", (conn, schema) => new MySqlHistoryContext(conn, schema)); //here s the thing.



        }

        protected override void Seed(CodeFirstMySql.Models.Context context){}//ommited
    }
}

然后 Update-Database -Verbose 玩得开心!

最佳答案

Adding custom MigrationHistory context 转述答案...

EF6 使用 MigrationHistory 表来跟踪模型更改并确保数据库架构和概念架构之间的一致性。默认情况下,此表不适用于 MySQL,因为主键太大。要解决这种情况,您需要缩小该表的键大小。

本质上,EF6 允许您使用 Fluent API 修改 MigrationId/ContextKey 索引列的键大小,如下所示:

modelBuilder.Entity<HistoryRow>().Property(h => h.MigrationId).HasMaxLength(100).IsRequired();
modelBuilder.Entity<HistoryRow>().Property(h => h.ContextKey).HasMaxLength(200).IsRequired();

Complete Instructions Here...

关于c# - 带有 MySql 和迁移的 Entity Framework 因 "max key length is 767 bytes"而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20832546/

相关文章:

c# - Entity Framework 4 和 Poco 以及 Linq2Sql 性能

c# - System.Web.dll 中发生类型 'System.InvalidOperationException' 的异常,但未在用户代码中处理

c# - 我如何在部分类中使用 "override"方法?

sql - Mysql 查询 - 组函数的无效使用

php - 使用 PHP 格式化表格

c# - 具有相同结构的多个表 Entity Framework

c# - 服务器协议(protocol)冲突错误

c# - 检查 HtmlString 在 C# 中是否为空格

mysql - 什么数据库用于 3D 距离计算?

sql-server - 在 MSSQL 中检索 varbinary 值作为 BASE64