我刚开始使用Entity Framework(4.3.1),并且正在使用MySQL EF提供程序(6.5.4)建立具有TPT继承的代码优先模型。尝试创建数据库结构时,我收到一个MySQLException "Identifier name 'LongClassNameOne_TypeConstraint_From_ClassName2s_To_LongClassNameOnes' is too long"
(这是将派生类的表与父类的表相关的关系。)
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()
...
我如何控制该名称以使其更短,或强制将其修剪为64个字符的名称限制,或类似这些内容?
您需要使用较短的表名,因为无法配置约束的名称。请注意,您无需更改类名即可。您可以在OnModelCreating中使用Table属性或使用.ToTable()方法。
为了扩大我之前对...的评论
如果您只是可以更改表名-然后在OnModelCreating中使用映射-as @Pawel suggested
,那可能是所有方法中最简单的解决方案。
但是,如果您只想更改关系的名称,
...通过在SqlGenerator
中提供自定义的SqlServerMigrationSqlGenerator
(即Configuration()
),您可以微管理需要时生成的实际sql(在某些一般情况下,它可能是通用的自动化解决方案) 。例如
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);
}
}
...或类似内容(您需要匹配,找到正确的命名-或比较Name Length
并在需要时将其缩短。在您的配置中(由迁移生成的文件)...
public Configuration()
{
AutomaticMigrationsEnabled = false;
SetSqlGenerator("MySqlMigrationSqlGenerator", new MySqlGenerator());
// SetSqlGenerator("System.Data.SqlClient", new MySqlGenerator());
}
((注:我不确定,但是(@Mariusz Jamro)建议MySQL提供者的名称为MySqlMigrationSqlGenerator
,我想这很合理)]
...这应该更改关系的FK-尽可能快地测试它可以正常工作,因为在C#中,模型中并没有真正使用关系名称(通常只是一个db名称)。