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?
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.
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).
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With