Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generated Identifier Too Long For Constraint Name

I am just getting started with Entity Framework (4.3.1) and am making a code-first model with TPT inheritance using the MySQL EF provider (6.5.4). When attempting to create the database structure, I am receiving a MySQLException "Identifier name 'LongClassNameOne_TypeConstraint_From_ClassName2s_To_LongClassNameOnes' is too long" (This is the relation which relates the derived class's table to the parent class's table.)

   at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
   at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int32& insertedId)
   at MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int32& insertedId)
   at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
   at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader()
   at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
   at MySql.Data.MySqlClient.MySqlScript.Execute()
   at MySql.Data.MySqlClient.MySqlProviderServices.DbCreateDatabase(DbConnection connection, Nullable`1 commandTimeout, StoreItemCollection storeItemCollection)
   at System.Data.Objects.ObjectContext.CreateDatabase()
   at System.Data.Entity.Internal.DatabaseOperations.Create(ObjectContext objectContext)
   at System.Data.Entity.Internal.DatabaseCreator.CreateDatabase(InternalContext internalContext, Func`3 createMigrator, ObjectContext objectContext)
   at System.Data.Entity.Internal.InternalContext.CreateDatabase(ObjectContext objectContext)
   at System.Data.Entity.Database.Create()
   at System.Data.Entity.DropCreateDatabaseAlways`1.InitializeDatabase(TContext context)
   at System.Data.Entity.Database.<>c__DisplayClass2`1.<SetInitializerInternal>b__0(DbContext c)
   at System.Data.Entity.Internal.InternalContext.<>c__DisplayClass8.<PerformDatabaseInitialization>b__6()
   at System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action)
   at System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization()
   at System.Data.Entity.Internal.LazyInternalContext.<InitializeDatabase>b__4(InternalContext c)
   at System.Data.Entity.Internal.RetryAction`1.PerformAction(TInput input)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action`1 action)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase()
   at System.Data.Entity.Internal.InternalContext.Initialize()
   at System.Data.Entity.Internal.InternalContext.ForceOSpaceLoadingForKnownEntityTypes()
   at System.Data.Entity.DbContext.System.Data.Entity.Infrastructure.IObjectContextAdapter.get_ObjectContext()
   ...

How can I control this name to make it shorter, or force it to be trimmed to the 64-character name limit, or something along these lines?

like image 491
Dark Falcon Avatar asked Apr 28 '12 23:04

Dark Falcon


People also ask

What is identifier in SQL?

The database object name is referred to as its identifier. Everything in Microsoft SQL Server can have an identifier. Servers, databases, and database objects, such as tables, views, columns, indexes, triggers, procedures, constraints, and rules, can have identifiers.

What is the max length of column name in mysql?

Aliases for column names in CREATE VIEW statements are checked against the maximum column length of 64 characters (not the maximum alias length of 256 characters).


2 Answers

You need to use shorter table name as there is no way to configure names of constraints. Note that you don't need to change class names to do that. You can either use Table attribute or use .ToTable() method in OnModelCreating.

like image 199
Pawel Avatar answered Sep 30 '22 19:09

Pawel


To expand on my comment earlier on...

If you can just change the table name - then go with the mapping in the OnModelCreating - as @Pawel suggested, that's likely the easiest solution of all.

However, if you'd like to change just the name of the relation,

...by providing a custom SqlGenerator (i.e. the SqlServerMigrationSqlGenerator) in the Configuration() you can micro-manage the actual sql generated when needed (and that might be the generic, automated solution in some general case). e.g.

public class MySqlGenerator : SqlServerMigrationSqlGenerator
{
    protected override void Generate(AddForeignKeyOperation addForeignKeyOperation)
    {
        if (addForeignKeyOperation.Name == "LongClassNameOne_TypeConstraint_From_ClassName2s_To_LongClassNameOnes")
            addForeignKeyOperation.Name = "MyCustomFKName";
        // addForeignKeyOperation.Name = "Test" + addForeignKeyOperation.Name;
        base.Generate(addForeignKeyOperation);
    }
}

...or something along those lines (you need to match, find the right naming - or compare the Name Length and shorten it where needed. And in your Configuration (file generated by migrations)...

public Configuration()
{
    AutomaticMigrationsEnabled = false;
    SetSqlGenerator("MySqlMigrationSqlGenerator", new MySqlGenerator());
    // SetSqlGenerator("System.Data.SqlClient", new MySqlGenerator());
}

(note: I don't know for sure but it was suggested (by @Mariusz Jamro) that the MySQL provider's name is MySqlMigrationSqlGenerator, makes sense I guess)

...this should change the FK of the relation - and as far as could test this fast it works ok, as the relation name is not really used in the model from C# (just a db name normally).

like image 32
NSGaga-mostly-inactive Avatar answered Sep 30 '22 18:09

NSGaga-mostly-inactive