指定的密钥太长;实体框架 6 中的最大密钥长度为 767 字节 Mysql 错误

Posted

技术标签:

【中文标题】指定的密钥太长;实体框架 6 中的最大密钥长度为 767 字节 Mysql 错误【英文标题】:Specified key was too long; max key length is 767 bytes Mysql error in Entity Framework 6 【发布时间】:2014-09-18 20:02:12 【问题描述】:

我已经开始使用 Visual Studio 2012 开发 Asp.net Mvc-5 应用程序。所以我从 nuget 下载了 Entity Framework-6 和 mysql 6.8.3.0。当我尝试使用 db Context 命令创建数据库时

dbContext.Database.CreateIfNotExists();

抛出这个异常。

指定的密钥太长;最大密钥长度为 767 字节

我已经对其进行了搜索,但找不到任何解决方案。我在搜索过程中得到的一件事,这可能是 Unicode 字符问题。我不知道如何处理这个问题。

更新

我正在使用以下配置

<configuration>
  <configSections>
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <entityFramework>
    <providers>
      <provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" />
    </providers>
  </entityFramework>
  <system.data>
    <DbProviderFactories>
      <remove invariant="MySql.Data.MySqlClient" />
      <add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.8.3.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
    </DbProviderFactories>
  </system.data>
</configuration>

我的数据库上下文类。我已经删除了所有模型,只保留了一个模型

public class MyContext : DbContext

    public MyContext()
        : base("myconn")
    
        this.Configuration.ValidateOnSaveEnabled = false;
    

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    
        modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention>();
        base.OnModelCreating(modelBuilder);
    

    public DbSet<ModelOne> ModelOne  get; set; 


模型类

public class  ModelOne

        [Key]
        public int CreatedId  get; set; 
        public Nullable<int> UserId  get; set; 
        public Nullable<DateTime> Date  get; set; 
        public string Description  get; set; 
  

谁能帮我解决这个问题?

谢谢。

【问题讨论】:

可以支持 Code-First 和 MySQL 迁移,但需要更改配置。见blog.devart.com/… 我使用相同的配置,但仍然面临同样的问题 您有注册 Code-First 和迁移的 Configuration 类的示例吗?即this.SetSqlGenerator() .... 【参考方案1】:

我已经更改了 DbContext 的 DbConfigurationType。

从此链接获得***

现在可以了

[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
public class MyContext : DbContext

    public MyContext()
        : base("myconn")
    
        this.Configuration.ValidateOnSaveEnabled = false;
    

    static MyContext()
    
            DbConfiguration.SetConfiguration(new MySql.Data.Entity.MySqlEFConfiguration());
    

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    
        modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention>();
        base.OnModelCreating(modelBuilder);
    

    public DbSet<ModelOne> ModelOne  get; set; 


【讨论】:

工作就像一个魅力!我只需要将属性添加到类中,事情就完美地起飞了。 为我工作,只需要做这个属性。我认为方法变体是为那些不想用属性装饰的人准备的。 其实只要在汇编中使用[DbConfigurationType(typeof(MySqlEFConfiguration))]就足够了。【参考方案2】:

看看这个article 看看它是否有帮助。特别是添加了MySqlHistoryContext.csConfiguration.csMySqlInitializer.cs 类。

您可以在这里找到解决方案。

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();
        
    

【讨论】:

【参考方案3】:

如果您已经尝试了这篇文章中的所有答案,但仍然出现错误,请尝试在 MySQL 服务器上运行此命令:

set GLOBAL storage_engine='InnoDb';

错误报告在这里:http://bugs.mysql.com/bug.php?id=4541

【讨论】:

感觉这应该是公认的答案。这是包含此解决方案的另一个线程:confluence.atlassian.com/fishkb/…【参考方案4】:

使用下面的配置代码...这解决了我的问题:

internal sealed class Configuration : DbMigrationsConfiguration<MDbContext>
       
    public Configuration()
    
        AutomaticMigrationsEnabled = false;
        CommandTimeout = 3600;

        DbConfiguration.SetConfiguration(new MySql.Data.Entity.MySqlEFConfiguration());
        SetSqlGenerator(MySql.Data.Entity.MySqlProviderInvariantName.ProviderName, new MySql.Data.Entity.MySqlMigrationSqlGenerator());
        SetHistoryContextFactory(MySql.Data.Entity.MySqlProviderInvariantName.ProviderName, (connection, schema) => new MySql.Data.Entity.MySqlHistoryContext(connection, schema));
    


【讨论】:

完美无瑕。这正是正确的答案。我在文章的其他地方看到了这个的残余,并希望在这个线程中更明确地找到。 100% 成功。谢谢。【参考方案5】:

如果您使用的是 ASP.NET Identity,那么有 3 个地方会发生这种情况

    在迁移历史表中 IdentityRole 的 Name 属性 ApplicationUser 的 Username 和 Email 属性

我遇到的大多数文章都有一个解决方案,基本上将用户名和电子邮件的长度减少到 128 个字符。但是,我发现这是不可接受的,因为电子邮件地址的官方规范是 256 个 ansi 字符。

我的解决方案是:

    为电子邮件和用户名关闭 unicode 覆盖 MySqlMigrationSqlGenerator 并告诉它使用 latin1_general_ci collat​​e,它是 ansi 字符集。 减少角色名称的长度。这是可以接受的,因为角色名称不需要那么长 如 Internet 上的各种文章所述,减少历史迁移的密钥长度。

你可以在https://github.com/timdinhdotcom/MySql.AspNetIdentity找到我的解决方案

【讨论】:

+1 这解决了我在迁移执行CREATE UNIQUE index UserNameIndex on ApplicationUsers (UserName DESC) using HASH 并死掉的问题。【参考方案6】:

你必须看到这个链接 https://***.com/a/27082231/929740

在上下文类上添加 DbConfigurationTypeAttribute: [DbConfigurationType(typeof(MySqlEFConfiguration))] 在应用启动时调用 DbConfiguration.SetConfiguration(new MySqlEFConfiguration()) 在配置文件中设置 DbConfiguration 类型:

【讨论】:

【参考方案7】:

我通过运行解决了这个问题:

Enable-Migrations -EnableAutomaticMigrations -Force -ContextTypeName ApplicationDbContext

并且不创建初始迁移:

Update-Database

表的创建没有任何问题也没有错误

【讨论】:

【参考方案8】:

有一种简单的方法可以在 MYSQl 中将 NVARCHAR 字段更改为 varchar 在 IdentityModels.cs 中添加此行

[DbConfigurationType(typeof(MySqlEFConfiguration))]
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, Role, int, UserLogin, UserRole, UserClaim>

    protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
    
        base.OnModelCreating(modelBuilder);

        //troca todos os campos NVARCHAR por varchar
        modelBuilder.Properties().Where(x =>
          x.PropertyType.FullName.Equals("System.String") &&
         !x.GetCustomAttributes(false).OfType<ColumnAttribute>().Where(q => q.TypeName != null && q.TypeName.Equals("varchar(max)", StringComparison.InvariantCultureIgnoreCase)).Any())
          .Configure(c =>
             c.HasColumnType("varchar(65000)"));

        modelBuilder.Properties().Where(x =>
          x.PropertyType.FullName.Equals("System.String") &&
         !x.GetCustomAttributes(false).OfType<ColumnAttribute>().Where(q => q.TypeName != null && q.TypeName.Equals("nvarchar", StringComparison.InvariantCultureIgnoreCase)).Any())
          .Configure(c =>
             c.HasColumnType("varchar"));
    

    public ApplicationDbContext()  : base("DefaultConnection")
    

    

    public static ApplicationDbContext Create()
    
        return new ApplicationDbContext();
    

【讨论】:

以上是关于指定的密钥太长;实体框架 6 中的最大密钥长度为 767 字节 Mysql 错误的主要内容,如果未能解决你的问题,请参考以下文章

DatabaseError: (1071, '指定的密钥太长;最大密钥长度为 767 字节')

指定的密钥太长;最大密钥长度为 767 字节

为啥会出现此错误 #1071 - 指定的密钥太长;最大密钥长度为 1000 字节? [复制]

#1071 - 指定的密钥太长;最大密钥长度为 767 字节

语法错误或访问冲突:1071 指定的密钥太长;最大密钥长度为 767 字节 [重复]

错误:#1071 - 指定的密钥太长;最大密钥长度为 1000 字节 - mysql 5.0.91