// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. namespace System.Data.Entity.Migrations { using System.Collections.Generic; using System.Data.Entity.Core.Metadata.Edm; using System.Data.Entity.Infrastructure; using System.Data.Entity.Migrations.Design; using System.Data.Entity.Migrations.History; using System.Data.Entity.Migrations.Model; using System.Data.Entity.Utilities; using System.Linq; using FunctionalTests.SimpleMigrationsModel; using Xunit; [Variant(DatabaseProvider.SqlClient, ProgrammingLanguage.CSharp)] [Variant(DatabaseProvider.SqlServerCe, ProgrammingLanguage.CSharp)] [Variant(DatabaseProvider.SqlClient, ProgrammingLanguage.VB)] public class UpgradeScenarios : DbTestCase { public class Ef5MigrationsContext : DbContext { public DbSet Blogs { get; set; } } public class Ef5MigrationsConfiguration : DbMigrationsConfiguration { public Ef5MigrationsConfiguration() { MigrationsNamespace = "FunctionalTests.SimpleMigrationsModel"; } } [MigrationsTheory] public void Can_upgrade_from_5_and_existing_code_migrations_still_work() { ResetDatabase(); var migrationsConfiguration = new Ef5MigrationsConfiguration { TargetDatabase = new DbConnectionInfo(ConnectionString, TestDatabase.ProviderName) }; var migrator = new DbMigrator(migrationsConfiguration); migrator.Update(); Assert.True(TableExists("dbo.Blogs")); Assert.True(TableExists("dbo." + HistoryContext.TableName)); migrator.Update("0"); Assert.False(TableExists("dbo.Blogs")); Assert.False(TableExists("dbo." + HistoryContext.TableName)); } [MigrationsTheory] public void Can_upgrade_from_5_and_existing_database_migrations_still_work() { ResetDatabase(); var migrationsConfiguration = new Ef5MigrationsConfiguration { TargetDatabase = new DbConnectionInfo(ConnectionString, TestDatabase.ProviderName) }; var migrator = new DbMigrator(migrationsConfiguration); migrator.Update(); var historyRepository = new HistoryRepository(ConnectionString, ProviderFactory, migrationsConfiguration.ContextKey); ExecuteOperations( new MigrationOperation[] { GetDropHistoryTableOperation(), GetCreateHistoryTableOperation() }); var model = CreateContext().GetModel(); // create v5 history rows ExecuteOperations( new[] { historyRepository.CreateInsertOperation("201112202056275_InitialCreate", model), historyRepository.CreateInsertOperation("201112202056573_AddUrlToBlog", model) }); migrator.Update("0"); Assert.False(TableExists("dbo.Blogs")); Assert.False(TableExists("dbo." + HistoryContext.TableName)); } [MigrationsTheory] public void Can_upgrade_from_5_and_existing_code_auto_migrations_still_work() { ResetDatabase(); var migrator = CreateMigrator(); migrator.Update(); var historyRepository = new HistoryRepository(ConnectionString, ProviderFactory, "MyKey"); // create v5 history rows ExecuteOperations( new[] { GetDropHistoryTableOperation(), GetCreateHistoryTableOperation(), historyRepository .CreateInsertOperation( "201112202056275_NoHistoryModelAutomaticMigration", CreateContext().GetModel()) }); migrator = CreateMigrator(); var scaffoldedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration_v2"); ResetDatabase(); migrator = CreateMigrator( scaffoldedMigrations: scaffoldedMigration, automaticDataLossEnabled: true); migrator.Update(); Assert.True(TableExists("crm.tbl_customers")); Assert.True(TableExists("dbo." + HistoryContext.TableName)); migrator.Update("0"); Assert.False(TableExists("crm.tbl_customers")); Assert.False(TableExists("dbo." + HistoryContext.TableName)); } [MigrationsTheory] public void Upgrade_from_earlier_version_should_upgrade_history_table_when_updating_generated() { ResetDatabase(); var createTableOperations = GetLegacyHistoryCreateTableOperations(); ExecuteOperations( createTableOperations.Concat( new[] { new SqlOperation( @"INSERT INTO [__MigrationHistory] ([MigrationId], [CreatedOn], [Model]) VALUES ('000000000000000_ExistingMigration', GETDATE(), 0x1F8B0800000000000400ECBD07601C499625262F6DCA7B7F4AF54AD7E074A10880601324D8904010ECC188CDE692EC1D69472329AB2A81CA6556655D661640CCED9DBCF7DE7BEFBDF7DE7BEFBDF7BA3B9D4E27F7DFFF3F5C6664016CF6CE4ADAC99E2180AAC81F3F7E7C1F3F22FEC7BFF71F7CFC7BBC5B94E9655E3745B5FCECA3DDF1CE4769BE9C56B36279F1D947EBF67CFBE0A3DFE3E8374E1E9FCE16EFD29F34EDF6D08EDE5C369F7D346FDBD5A3BB779BE93C5F64CD78514CEBAAA9CEDBF1B45ADCCD66D5DDBD9D9D83BBBB3B777302F111C14AD3C7AFD6CBB658E4FC07FD79522DA7F9AA5D67E517D52C2F1BFD9CBE79CD50D317D9226F56D934FFEC236ADB54657EBC5A95C5346B099DDD8FD2E3B2C80895D77979FE9E78ED3C045E1FD91EA9CF53C2ADBDA67EDAAC58E63577CEFDB6F9BBF6A3F4AEC3EEAEA067867177601C8FBFC8562B22A8372EFD247DAD83DA7EFDFE782F04C6DD69B3097DDB535BD5D945DEF916E39AE5CF8ABA699F666D36C99AFCA3F464B688348B0C5F61DBF177C6F958FBBCCDA4769090261FA52FEBEAB2980181D7D74D9B2FC668307EFD8BCA93B2C897AD6BF045B62CCEF3A67D53BDCDC1A044A3AFCF160FEFEEEC812DEE36CDACBC156FF468B8814BFA54797CD71788C74FF3A6B820E89E782CF32958DD01356DCE96E715D16095D7EDF5EBBCF571354DCCD78AEC17799BCD08CFE3BA2DCEB3694B5F4FF3A6A179FB28FDC9AC5C5393D3C5249F9D2DBF5CB7AB757BDC34F962525E8763DADC3F8B4288F3E32F57F8CB6383AF3F0442B3A021E45F2E9FAC8B7266F17E969521ED874160CA3ECFE9735621AF5BFA995F5C5B482FAAE52D0129F99EE6AB7C3923967C932F5625016BBE5CBECE2EF361DC6EA66148B1C74F8BECA2CE163E05E513C5E475463D7B5D5007FE1BAE3FFAF3F15D28F4A3FF270000FFFF4817137F02060000)") }).ToArray()); var migrator = CreateMigrator(); var generatedMigration = new MigrationScaffolder(migrator.Configuration).Scaffold("Migration1"); migrator = CreateMigrator( automaticMigrationsEnabled: false, scaffoldedMigrations: new[] { generatedMigration }); Assert.False(ColumnExists(HistoryContext.TableName, "ProductVersion")); Assert.False(ColumnExists(HistoryContext.TableName, "ContextKey")); Assert.True(ColumnExists(HistoryContext.TableName, "Hash")); Assert.True(ColumnExists(HistoryContext.TableName, "CreatedOn")); migrator.Update(generatedMigration.MigrationId); Assert.True(ColumnExists(HistoryContext.TableName, "ProductVersion")); Assert.True(ColumnExists(HistoryContext.TableName, "ContextKey")); Assert.False(ColumnExists(HistoryContext.TableName, "Hash")); Assert.False(ColumnExists(HistoryContext.TableName, "CreatedOn")); } [MigrationsTheory] public void Upgrade_from_earlier_version_should_upgrade_history_table_when_updating_automatic() { ResetDatabase(); var createTableOperations = GetLegacyHistoryCreateTableOperations(); ExecuteOperations( createTableOperations.Concat( new[] { new SqlOperation( @"INSERT INTO [__MigrationHistory] ([MigrationId], [CreatedOn], [Model]) VALUES ('000000000000000_ExistingMigration', GETDATE(), 0x1F8B0800000000000400ECBD07601C499625262F6DCA7B7F4AF54AD7E074A10880601324D8904010ECC188CDE692EC1D69472329AB2A81CA6556655D661640CCED9DBCF7DE7BEFBDF7DE7BEFBDF7BA3B9D4E27F7DFFF3F5C6664016CF6CE4ADAC99E2180AAC81F3F7E7C1F3F22FEC7BFF71F7CFC7BBC5B94E9655E3745B5FCECA3DDF1CE4769BE9C56B36279F1D947EBF67CFBE0A3DFE3E8374E1E9FCE16EFD29F34EDF6D08EDE5C369F7D346FDBD5A3BB779BE93C5F64CD78514CEBAAA9CEDBF1B45ADCCD66D5DDBD9D9D83BBBB3B777302F111C14AD3C7AFD6CBB658E4FC07FD79522DA7F9AA5D67E517D52C2F1BFD9CBE79CD50D317D9226F56D934FFEC236ADB54657EBC5A95C5346B099DDD8FD2E3B2C80895D77979FE9E78ED3C045E1FD91EA9CF53C2ADBDA67EDAAC58E63577CEFDB6F9BBF6A3F4AEC3EEAEA067867177601C8FBFC8562B22A8372EFD247DAD83DA7EFDFE782F04C6DD69B3097DDB535BD5D945DEF916E39AE5CF8ABA699F666D36C99AFCA3F464B688348B0C5F61DBF177C6F958FBBCCDA4769090261FA52FEBEAB2980181D7D74D9B2FC668307EFD8BCA93B2C897AD6BF045B62CCEF3A67D53BDCDC1A044A3AFCF160FEFEEEC812DEE36CDACBC156FF468B8814BFA54797CD71788C74FF3A6B820E89E782CF32958DD01356DCE96E715D16095D7EDF5EBBCF571354DCCD78AEC17799BCD08CFE3BA2DCEB3694B5F4FF3A6A179FB28FDC9AC5C5393D3C5249F9D2DBF5CB7AB757BDC34F962525E8763DADC3F8B4288F3E32F57F8CB6383AF3F0442B3A021E45F2E9FAC8B7266F17E969521ED874160CA3ECFE9735621AF5BFA995F5C5B482FAAE52D0129F99EE6AB7C3923967C932F5625016BBE5CBECE2EF361DC6EA66148B1C74F8BECA2CE163E05E513C5E475463D7B5D5007FE1BAE3FFAF3F15D28F4A3FF270000FFFF4817137F02060000)") }).ToArray()); var migrator = CreateMigrator(); Assert.False(ColumnExists(HistoryContext.TableName, "ProductVersion")); Assert.False(ColumnExists(HistoryContext.TableName, "ContextKey")); Assert.True(ColumnExists(HistoryContext.TableName, "Hash")); Assert.True(ColumnExists(HistoryContext.TableName, "CreatedOn")); migrator.Update(); Assert.True(ColumnExists(HistoryContext.TableName, "ProductVersion")); Assert.True(ColumnExists(HistoryContext.TableName, "ContextKey")); Assert.False(ColumnExists(HistoryContext.TableName, "Hash")); Assert.False(ColumnExists(HistoryContext.TableName, "CreatedOn")); } private IEnumerable GetLegacyHistoryCreateTableOperations() { const string tableName = "dbo." + HistoryContext.TableName; var createTableOperation = new CreateTableOperation(tableName); createTableOperation.Columns.Add( new ColumnModel(PrimitiveTypeKind.String) { Name = "MigrationId", MaxLength = 255, IsNullable = false }); createTableOperation.Columns.Add( new ColumnModel(PrimitiveTypeKind.DateTime) { Name = "CreatedOn" }); createTableOperation.Columns.Add( new ColumnModel(PrimitiveTypeKind.Binary) { Name = "Model" }); createTableOperation.Columns.Add( new ColumnModel(PrimitiveTypeKind.String) { Name = "Hash" }); yield return createTableOperation; var addPrimaryKeyOperation = new AddPrimaryKeyOperation { Table = tableName }; addPrimaryKeyOperation.Columns.Add("MigrationId"); yield return addPrimaryKeyOperation; } } }