EF5 Code First Migrations: "Les noms des colonnes dans chaque table doivent être uniques" après l'utilisation de RenameColumn

Nous sommes à l'aide de Entity Framework 5.0 le Premier Code et les Migrations Automatiques.

J'ai eu une classe comme ceci:

public class TraversalZones
{
    public int Low { get; set; }
    public int High { get; set; }
}​

Puis nous avons réalisé ces propriétés n'ont pas vraiment le droit de noms, nous avons donc changé:

public class TraversalZones
{
    public int Left { get; set; }
    public int Top { get; set; }
}​

Le renommer refait correctement tout au long du projet, mais je sais que les Migrations Automatiques ne sont pas assez intelligents pour ramasser ces explicite renomme dans l'IDE, j'ai donc d'abord contrôlés afin de vérifier les seuls dans l'attente de la migration était cette colonne renommer:

update-database -f -script

Bien sûr il a juste montré le SQL abandon de Bas et de Haut et en ajoutant en Haut et à Gauche. J'ai ensuite ajouté une migration manuelle:

add-migration RenameColumns_TraversalZones_LowHigh_LeftTop

Et fixe le code généré simplement:

public override void Up()
{
    RenameColumn("TraversalZones", "Low", "Left");
    RenameColumn("TraversalZones", "High", "Top");
}

public override void Down()
{
    RenameColumn("TraversalZones", "Left", "Low");
    RenameColumn("TraversalZones", "Top", "High");
}

J'ai ensuite mis à jour la db:

update-database -verbose

Et a obtenu 2 colonne renomme, tout comme je m'attendais.

Plusieurs migrations plus tard, j'ai sauvegardé la Production et l'a restitué à un local DB pour tester le code sur cette DB. Cette DB eu le TraversalZones tableau déjà créé, avec les anciens noms de colonne (Basse et Haute) j'ai bien sûr commencé par la mise à jour:

update-database -f -verbose

Et le renommer les commandes apparu dans la sortie - tout semblait bien:

EXECUTE sp_rename @objname = N'TraversalZones.Low', @newname = N'Left', @objtype = N'COLUMN'
EXECUTE sp_rename @objname = N'TraversalZones.High', @newname = N'Top', @objtype = N'COLUMN'
[Inserting migration history record]

J'ai ensuite couru mon code, et il erronées out me dit que la base de données a changé depuis la dernière exécution, et que je devrais courir update-database... .

J'ai donc couru de nouveau:

update-database -f -verbose

Et je suis maintenant bloqué sur ce message d'erreur:

No pending code-based migrations. Applying automatic migration:
201212191601545_AutomaticMigration.
ALTER TABLE [dbo].[TraversalZones] ADD [Left] [int] NOT NULL DEFAULT 0
System.Data.SqlClient.SqlException (0x80131904): Column names in each table must be unique. Column name 'Left' in table 'dbo.TraversalZones' is specified more than once.
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async, Int32 timeout)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at System.Data.Entity.Migrations.DbMigrator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement)
at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable`1 migrationStatements)
at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, XDocument targetModel, IEnumerable`1 operations, Boolean downgrading, Boolean auto)
at System.Data.Entity.Migrations.DbMigrator.AutoMigrate(String migrationId, XDocument sourceModel, XDocument targetModel, Boolean downgrading)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.AutoMigrate(String migrationId, XDocument sourceModel, XDocument targetModel, Boolean downgrading)
at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.RunCore()
at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run()
ClientConnectionId:c40408ee-def3-4553-a9fb-195366a05fff
Column names in each table must be unique. Column name 'Left' in table 'dbo.TraversalZones' is specified more than once.​

Il apparaît donc clairement que les Migrations, il est confus quant à savoir si la colonne "Gauche" a encore à faire dans ce tableau; je suppose RenameColumn serait de laisser les choses en l'état, mais il semble qu'il n'a pas.

Quand je dump ce qu'il tente de faire pour un update-database -f -scriptje l'obtiens en essayant de faire exactement ce qu'elle aurait fait si la migration manuelle n'étaient pas là:

ALTER TABLE [dbo].[TraversalZones] ADD [Left] [int] NOT NULL DEFAULT 0
ALTER TABLE [dbo].[TraversalZones] ADD [Top] [int] NOT NULL DEFAULT 0
DECLARE @var0 nvarchar(128)
SELECT @var0 = name
FROM sys.default_constraints
WHERE parent_object_id = object_id(N'dbo.TraversalZones')
AND col_name(parent_object_id, parent_column_id) = 'Low';
IF @var0 IS NOT NULL
EXECUTE('ALTER TABLE [dbo].[TraversalZones] DROP CONSTRAINT ' + @var0)
ALTER TABLE [dbo].[TraversalZones] DROP COLUMN [Low]
DECLARE @var1 nvarchar(128)
SELECT @var1 = name
FROM sys.default_constraints
WHERE parent_object_id = object_id(N'dbo.TraversalZones')
AND col_name(parent_object_id, parent_column_id) = 'High';
IF @var1 IS NOT NULL
EXECUTE('ALTER TABLE [dbo].[TraversalZones] DROP CONSTRAINT ' + @var1)
ALTER TABLE [dbo].[TraversalZones] DROP COLUMN [High]
INSERT INTO [__MigrationHistory] ([MigrationId], [Model], [ProductVersion]) VALUES ('201212191639471_AutomaticMigration', 0x1F8B08000...000, '5.0.0.net40')

Ce qui semble être un bogue dans les Migrations.

source d'informationauteur Chris Moschini