10

我刚刚开始使用 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 个字符的名称限制,或类似的东西?

4

2 回答 2

6

您需要使用较短的表名,因为无法配置约束名称。请注意,您无需更改类名即可执行此操作。您可以在 OnModelCreating 中使用 Table 属性或使用 .ToTable() 方法。

于 2012-04-29T15:23:50.330 回答
6

为了扩展我之前的评论...

如果您可以更改表名 - 然后使用 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 名称)。

于 2012-04-29T18:02:21.317 回答