指定的密钥太长;实体框架 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.cs
、Configuration.cs
和MySqlInitializer.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 collate,它是 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 字节')
为啥会出现此错误 #1071 - 指定的密钥太长;最大密钥长度为 1000 字节? [复制]
#1071 - 指定的密钥太长;最大密钥长度为 767 字节