web-dev-qa-db-fra.com

La clé spécifiée était trop longue. La longueur maximale de la clé est de 767 octets. Erreur Mysql dans Entity Framework 6.

J'ai commencé à travailler sur l'application Asp.net Mvc-5 à l'aide de visual studio 2012. J'ai donc téléchargé Entity Framework-6 et MySQL 6.8.3.0 de Nuget. Lorsque j'ai essayé de créer une base de données à l'aide de la commande db Context

dbContext.Database.CreateIfNotExists();

Cette exception levée.

La clé spécifiée était trop longue. la longueur maximale de la clé est de 767 octets

J'ai fait des recherches à ce sujet, mais je ne trouve aucune solution. Une chose que j'ai eu lors de ma recherche, cela peut être un problème de caractères Unicode. Je ne sais pas comment traiter ce problème.

Mis à jour

J'utilise la configuration suivante

<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>

Ma classe de contexte DB. J'ai enlevé tous les modèles, il ne reste plus qu'un modèle à gauche

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; }

}

Classe de modèle

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; }
  }

Quelqu'un peut-il m'aider avec ce problème?

Je vous remercie.

16
Shoaib Ijaz

J'ai changé le DbConfigurationType de DbContext.

Obtenu de ce lien stackoverflow

Maintenant ça marche

[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; }

}
38
Shoaib Ijaz

Si vous utilisez ASP.NET Identity, il y a 3 endroits où cela se produit

  1. Dans la table d'historique de migration
  2. La propriété Name de IdentityRole
  3. Les propriétés Username et Email de ApplicationUser

La plupart des articles que j'ai rencontrés ont une solution qui réduit la longueur du nom d'utilisateur et de l'e-mail à 128 caractères. Cependant, j’ai trouvé que c’était inacceptable, car la spécification officielle de l’adresse électronique est de 256 caractères ansi. 

Ma solution était de:

  1. Désactiver Unicode pour le courrier électronique et le nom d'utilisateur
  2. remplacez MySqlMigrationSqlGenerator et dites-lui d'utiliser latin1_general_ci collate, qui est un jeu de caractères ansi.
  3. réduire la longueur du nom du rôle. Ceci est acceptable car le nom du rôle n'a pas besoin d'être aussi long
  4. réduisez la longueur de clé pour la migration de l'historique comme décrit dans divers articles sur Internet.

Vous pouvez trouver ma solution sur https://github.com/timdinhdotcom/MySql.AspNetIdentity

5
Tien Dinh

Jetez un oeil à cet article et voyez si cela vous aide. En particulier, les classes MySqlHistoryContext.cs, Configuration.cs et MySqlInitializer.cs ont été ajoutées.

C'est ici que vous trouverez votre solution.

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();
        }
    }
2
Kinyanjui Kamau

Utilisez le code de configuration ci-dessous ... Ceci a résolu mon problème:

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

}
1
Alper Ebicoglu

Il existe un moyen simple de modifier les champs NVARCHAR en varchar dans MYSQl et d'ajouter ces lignes dans 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();
    }
}
1
Rodrigo Zimmermann

Si vous avez essayé toutes les réponses de cet article et que l'erreur persiste, essayez alors d'exécuter cette commande sur le serveur MySQL:

set GLOBAL storage_engine='InnoDb';

Le bogue a été signalé ici: http://bugs.mysql.com/bug.php?id=4541

0
Pabinator

Vous devez voir ce lien https://stackoverflow.com/a/27082231/929740

  • Ajout de DbConfigurationTypeAttribute sur la classe de contexte: [DbConfigurationType (typeof (MySqlEFConfiguration))]
  • Appel de DbConfiguration.SetConfiguration (new MySqlEFConfiguration ()) au démarrage de l'application
  • Définissez le type DbConfiguration dans le fichier de configuration:

<entityFramework codeConfigurationType = "MySql.Data.Entity.MySqlEFConfiguration, MySql.Data.Entity.EF6">

0
Kim Ki Won

Je me suis débarrassé de ce problème en exécutant:

Enable-Migrations -EnableAutomaticMigrations -Force -ContextTypeName ApplicationDbContext

Et sans créer de migration initiale:

Update-Database

Les tables ont été créées sans aucun problème ni erreur

0
Jorge Cuevas