14

kullandıktan sonra "Her tablonun sütun adları benzersiz olmalıdır" hatası Entity Framework 5.0 Kod İlk ve Otomatik Geçişler kullanıyoruz. EF5 Kod İlk Geçişler: RenameColumn

bir sınıf şöyle oldu:
public class TraversalZones 
{ 
    public int Low { get; set; } 
    public int High { get; set; } 
}​ 

Sonra bu özellikler gerçekten doğru isimler değildi fark ettik ve onları değiştirdi:

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

proje boyunca düzgün refactored yeniden adlandırma

: ama bu sütun yeniden adlandırma oldu ben Otomatik Taşıma IDE içinde bu açık yeniden adlandırır tespit edecek kadar akıllı olmadığını biliyoruz, bu yüzden ilk sadece bekleyen göç doğrulamak için kontrol Tabii

sadece Low ve High bırakarak ve Sol ve Üst ekleyerek SQL gösterdi. Sonra manuel göç ekledi:

add-migration RenameColumns_TraversalZones_LowHigh_LeftTop 

Ve basitçe oluşturulan kodu yukarı sabit:

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

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

Sonra db güncelleme:

update-database -verbose 

Ve 2 sütun yeniden adlandırır var , beklediğim gibi.

Çeşitli göçler sonra ben Üretim yedeklenmiş ve bu veritabanındaki kodu test etmek için bir yerel DB bunu geri yüklendi. Bu DB elbette bunu güncelleyerek başladı eski sütun adları (Alçak ve Yüksek) ile zaten oluşturulmuş TraversalZones tablo vardı:

update-database -f -verbose 

Ve yeniden adlandırma komutları çıktıda çıktı - tüm iyi çıktı:

...
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] 

o zaman benim kod koştum, ve beni veritabanı geçen yayınlandığından değişti ve ben update-database çalıştırmak gerektiğini vardı söylüyorum hata bildiren.

update-database -f -verbose 

Ve şimdi bu hata şaşırıp:

Bu yüzden tekrar ran Yani

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.​ 

açıkça Göçler "Sol" sütunu hala yapması gereken olmadığına dair kafası karışık bu tabloya; RenameColumn'un işleri doğru durumda bırakacağını sanırım, ama öyle değil. Ben bir update-database -f -script için yapmaya çalıştığınızı ne dökümü zaman

, ben manuel göç değil olsaydı o yapardı tam olarak ne yapmaya çalışıyor olsun:

Bu bir hata gibi görünen
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') 

göçler.

cevap

15

geçici çözüm, belli ki, şudur: Benim Söz konusu sonuçlarını görebilirsiniz

update-database -f -script 

. Ardından, komut dosyasından ancak son satırdan her şeyi fırlattım ve bunu, Migrations'a bildirmek için DB'ye karşı koştum: Bu sütunu zaten yeniden adlandırdık, kesmiştik.

Veritabanının bu kopyasına ilişkin ile devam edebilirim ancak üretimin kopyalanmasına (Üretimin kendisi taşınana kadar) her geçişin bu sorunu yaşamaya devam etmesiyle ilgileniyorum. Bu geçici çözüm olmadan bunu nasıl düzgün bir şekilde çözebilirim?

Güncelleme Bu aslında Üretiminde dahil her durumda bir konuydu. Kirli çözüm, üretilen sürümü ve sabit sürümü işledikten sonra bir SQL betiği (update-database -f -script) oluşturmaktı. böylece harfiyen uymaya

public void Up() 
{ 
    Sql("...That SQL you extracted from the script..."); 
} 

Bu, bu göç çalışan diğer ortamları sağlayacak:

Biraz daha temiz bir çözüm, komut SQL almak manuel göç ekleyin ve Up içeriğini basitçe etmek değiştirmektir istediğin şekilde. Her ihtimale karşı

  1. Yedekleme db: Eğer bu şekilde yaklaşabilir böylece

    Test bu biraz zordur.

  2. SQL'i çalıştırın. Düzgün çalışıyorsa, SQL'i bir kenara koyun.
  3. Manuel geçişi ekleyin ve Up() yöntemindeki her şeyi silin. Tamamen boş bırak.
  4. Güncelleştirme-veritabanı -f'yi çalıştırın -f
  5. Şimdi, bir kenara ayarladığınız SQL'i arayarak Sql("..."); ekleyerek Up() yöntemini değiştirin.

Şimdi db'niz SQL'i iki kez çalıştırmadan günceldir ve diğer ortamlar bu SQL'in sonuçlarını alır.