Указанный ключ был слишком длинным; максимальная длина ключа составляет 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 места, где это происходит

  1. В таблице истории миграции
  2. Свойство Name объекта IdentityRole
  3. Имя пользователя и адрес электронной почты ApplicationUser

В большинстве статей, с которыми я сталкивался, есть решение, которое в основном сокращает длину имени пользователя и электронной почты до 128 символов. Тем не менее, я обнаружил, что это неприемлемо, потому что официальная спецификация для адреса электронной почты составляет 256 символов.

Мое решение было:

  1. Отключите Юникод для электронной почты и имени пользователя
  2. переопределите MySqlMigrationSqlGenerator и скажите ему использовать latin1_general_ci collate, который является набором символов ANSI.
  3. уменьшить длину имени роли. Это приемлемо, так как имя роли не должно быть таким длинным
  4. уменьшите длину ключа для миграции истории, как описано в различных статьях в Интернете.

Вы можете найти мое решение по адресу 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 в файле конфигурации:

Другие вопросы по тегам