Указанный ключ был слишком длинным; максимальная длина ключа составляет 767 байт. Mysql ошибка в Entity Framework 6
Я начал работать над приложением Asp.net Mvc-5, используя Visual Studio 2012. Поэтому я скачал Entity Framework-6 и MySQL 6.8.3.0 из nuget. Когда я пытался создать базу данных с помощью команды 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; }
}
Кто-нибудь может мне помочь с этим вопросом?
Спасибо.
8 ответов
Я изменил DbConfigurationType DbContext.
Получил по этой ссылке стек переполнения
Сейчас работает
[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; }
}
Если вы используете ASP.NET Identity, то есть 3 места, где это происходит
- В таблице истории миграции
- Свойство Name объекта IdentityRole
- Имя пользователя и адрес электронной почты ApplicationUser
В большинстве статей, с которыми я сталкивался, есть решение, которое в основном сокращает длину имени пользователя и электронной почты до 128 символов. Тем не менее, я обнаружил, что это неприемлемо, потому что официальная спецификация для адреса электронной почты составляет 256 символов.
Мое решение было:
- Отключите Юникод для электронной почты и имени пользователя
- переопределите MySqlMigrationSqlGenerator и скажите ему использовать latin1_general_ci collate, который является набором символов ANSI.
- уменьшить длину имени роли. Это приемлемо, так как имя роли не должно быть таким длинным
- уменьшите длину ключа для миграции истории, как описано в различных статьях в Интернете.
Вы можете найти мое решение по адресу https://github.com/timdinhdotcom/MySql.AspNetIdentity
Если вы попробовали все ответы в этом посте и все еще получаете сообщение об ошибке, попробуйте выполнить эту команду на сервере MySQL:
set GLOBAL storage_engine='InnoDb';
Об ошибке сообщалось здесь: http://bugs.mysql.com/bug.php?id=4541
Используйте код конфигурации ниже... Это решило мою проблему:
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));
}
}
Посмотрите на эту статью и посмотрите, поможет ли это. Особенно 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();
}
}
Есть простой способ изменить поля NVARCHAR на varchar в MYSQl, добавить эти строки в 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();
}
}
Я избавился от этой проблемы, запустив:
Enable-Migrations -EnableAutomaticMigrations -Force -ContextTypeName ApplicationDbContext
И без создания начальной миграции:
Update-Database
Таблицы были созданы без проблем и ошибок.
Вы должны увидеть эту ссылку /questions/3892545/entity-framework-s-mysql-i-migrations-terpit-neudachu-potomu-chto-maksimalnaya-dlina-klyucha-sostavlyaet-767-bajtov/3892566#3892566
- Добавление атрибута DbConfigurationTypeAttribute в контекстный класс: [DbConfigurationType(typeof(MySqlEFConfiguration))]
- Вызов DbConfiguration.SetConfiguration(new MySqlEFConfiguration()) при запуске приложения
- Установите тип DbConfiguration в файле конфигурации: