Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

History table configuration part 1

- Move history table management into main pipeline.
- Adds history model metadata into user model metadata.
- Introduces IsSystem to MigrationOperation to differentiate history ops from users ops.
- Use IsSystem instead of anonymous arg in SQL gen to make history a system table.
- Added FTs for upgrade scenarios.
  • Loading branch information...
commit 9baca562ee3a747a41870f45e749e4436b6aca26 1 parent ba9a543
Andrew Peters authored July 20, 2012

Showing 29 changed files with 750 additions and 503 deletions. Show diff stats Hide diff stats

  1. 1  src/EntityFramework/EntityFramework.csproj
  2. 3  src/EntityFramework/Internal/DatabaseCreator.cs
  3. 165  src/EntityFramework/Migrations/DbMigrator.cs
  4. 15  src/EntityFramework/Migrations/Edm/EdmXNames.cs
  5. 129  src/EntityFramework/Migrations/History/HistoryRepository.cs
  6. 159  src/EntityFramework/Migrations/Infrastructure/EdmModelDiffer.cs
  7. 12  src/EntityFramework/Migrations/Infrastructure/MigratorBase.cs
  8. 4  src/EntityFramework/Migrations/Infrastructure/MigratorLoggingDecorator.cs
  9. 13  src/EntityFramework/Migrations/Infrastructure/MigratorScriptingDecorator.cs
  10. 2  src/EntityFramework/Migrations/Model/MigrationOperation.cs
  11. 6  src/EntityFramework/Migrations/Sql/SqlServerMigrationSqlGenerator.cs
  12. 9  src/EntityFramework/Utilities/DbContextExtensions.cs
  13. 18  src/EntityFramework/Utilities/DbModelExtensions.cs
  14. 7  src/EntityFramework/Utilities/XDocumentExtensions.cs
  15. 2  test/EntityFramework/FunctionalTests/FunctionalTests.csproj
  16. 4  test/EntityFramework/FunctionalTests/Migrations/DashScriptScenarios.cs
  17. 74  test/EntityFramework/FunctionalTests/Migrations/SchemaScenarios.cs
  18. 33  test/EntityFramework/FunctionalTests/Migrations/TestHelpers/DbTestCase.cs
  19. 145  test/EntityFramework/FunctionalTests/Migrations/UpgradeScenarios.cs
  20. 25  test/EntityFramework/FunctionalTests/TestHelpers/DbModelExtensions.cs
  21. 5  test/EntityFramework/UnitTests/Internal/DatabaseCreatorTests.cs
  22. 26  test/EntityFramework/UnitTests/Migrations/DbMigratorTests.cs
  23. 3  test/EntityFramework/UnitTests/Migrations/Edm/ModelCompressorTests.cs
  24. 159  test/EntityFramework/UnitTests/Migrations/History/HistoryRepositoryTests.cs
  25. 199  test/EntityFramework/UnitTests/Migrations/Infrastructure/EdmModelDifferTests.cs
  26. 2  test/EntityFramework/UnitTests/Migrations/Sql/SqlServerMigrationSqlGeneratorTests.cs
  27. 1  test/EntityFramework/UnitTests/UnitTests.csproj
  28. 19  test/EntityFramework/UnitTests/Utilities/DbModelExtensionsTests.cs
  29. 13  test/EntityFramework/UnitTests/Utilities/XDocumentExtensionsTests.cs
1  src/EntityFramework/EntityFramework.csproj
@@ -361,6 +361,7 @@
361 361
     <Compile Include="Internal\ProviderConfig.cs" />
362 362
     <Compile Include="Spatial\SpatialServicesLoader.cs" />
363 363
     <Compile Include="Utilities\BoolExtensions.cs" />
  364
+    <Compile Include="Utilities\DbModelExtensions.cs" />
364 365
     <Compile Include="Utilities\DbProviderFactoryExtensions.cs" />
365 366
     <Compile Include="Utilities\ExceptionExtensions.cs" />
366 367
     <Compile Include="Core\Common\FieldMetadata.cs" />
3  src/EntityFramework/Internal/DatabaseCreator.cs
@@ -5,6 +5,7 @@ namespace System.Data.Entity.Internal
5 5
     using System.Data.Entity.Core.Objects;
6 6
     using System.Data.Entity.Infrastructure;
7 7
     using System.Data.Entity.Migrations;
  8
+    using System.Data.Entity.Migrations.Infrastructure;
8 9
     using System.Data.Entity.Migrations.Sql;
9 10
     using System.Diagnostics.Contracts;
10 11
 
@@ -37,7 +38,7 @@ public DatabaseCreator(Lazy<IDbDependencyResolver> resolver)
37 38
         /// </summary>
38 39
         public virtual void CreateDatabase(
39 40
             InternalContext internalContext,
40  
-            Func<DbMigrationsConfiguration, DbContext, DbMigrator> createMigrator,
  41
+            Func<DbMigrationsConfiguration, DbContext, MigratorBase> createMigrator,
41 42
             ObjectContext objectContext)
42 43
         {
43 44
             Contract.Requires(internalContext != null);
165  src/EntityFramework/Migrations/DbMigrator.cs
@@ -112,7 +112,7 @@ internal DbMigrator(DbMigrationsConfiguration configuration, DbContext usersCont
112 112
                 _providerFactory = DbProviderServices.GetProviderFactory(connection);
113 113
 
114 114
                 _historyRepository
115  
-                    = new HistoryRepository(_usersContextInfo.ConnectionString, _providerFactory, context.InternalContext.DefaultSchema);
  115
+                    = new HistoryRepository(_usersContextInfo.ConnectionString, _providerFactory);
116 116
 
117 117
                 _providerManifestToken = context.InternalContext.ModelProviderInfo != null
118 118
                                              ? context.InternalContext.ModelProviderInfo.ProviderManifestToken
@@ -135,12 +135,12 @@ internal DbMigrator(DbMigrationsConfiguration configuration, DbContext usersCont
135 135
                 }
136 136
             }
137 137
 
138  
-            _emptyModel = new Lazy<XDocument>(
139  
-                () =>
140  
-                new DbModelBuilder().Build(
141  
-                    new DbProviderInfo(
142  
-                    _usersContextInfo.ConnectionProviderName,
143  
-                    _providerManifestToken)).GetModel());
  138
+            var providerInfo
  139
+                = new DbProviderInfo(_usersContextInfo.ConnectionProviderName, _providerManifestToken);
  140
+
  141
+            _emptyModel = new Lazy<XDocument>(() => new DbModelBuilder().Build(providerInfo).GetModel());
  142
+
  143
+            _historyRepository.AppendHistoryModel(_currentModel, providerInfo);
144 144
         }
145 145
 
146 146
         /// <summary>
@@ -332,7 +332,7 @@ public override void Update(string targetMigration)
332 332
                     () => ExecuteOperations(
333 333
                         MigrationAssembly.CreateBootstrapMigrationId(),
334 334
                         _currentModel,
335  
-                        new List<MigrationOperation>(),
  335
+                        _modelDiffer.Diff(_emptyModel.Value, _currentModel, true).Where(o => o.IsSystem),
336 336
                         false));
337 337
             }
338 338
 
@@ -472,7 +472,9 @@ private bool IsModelOutOfDate(XDocument model, DbMigration lastMigration)
472 472
         {
473 473
             Contract.Requires(model != null);
474 474
 
475  
-            return _modelDiffer.Diff(GetLastModel(lastMigration), model).Any();
  475
+            var sourceModel = GetLastModel(lastMigration);
  476
+
  477
+            return _modelDiffer.Diff(sourceModel, model, ReferenceEquals(sourceModel, _emptyModel.Value)).Any();
476 478
         }
477 479
 
478 480
         private XDocument GetLastModel(DbMigration lastMigration, string currentMigrationId = null)
@@ -509,24 +511,44 @@ internal override void Downgrade(IEnumerable<string> pendingMigrations)
509 511
 
510 512
                 Contract.Assert(targetModel != null);
511 513
 
  514
+                var sourceModel = _historyRepository.GetModel(migrationId);
  515
+
512 516
                 if (migration == null)
513 517
                 {
514  
-                    var sourceModel = _historyRepository.GetModel(migrationId);
515  
-
516 518
                     base.AutoMigrate(migrationId, sourceModel, targetModel, downgrading: true);
517 519
                 }
518 520
                 else
519 521
                 {
520  
-                    base.RevertMigration(migrationId, migration, targetModel);
  522
+                    base.RevertMigration(migrationId, migration, sourceModel, targetModel);
521 523
                 }
522 524
             }
523 525
         }
524 526
 
525  
-        internal override void RevertMigration(string migrationId, DbMigration migration, XDocument targetModel)
  527
+        internal override void RevertMigration(string migrationId, DbMigration migration, XDocument sourceModel, XDocument targetModel)
526 528
         {
  529
+            var includeSystemOps = false;
  530
+
  531
+            if (ReferenceEquals(targetModel, _emptyModel.Value))
  532
+            {
  533
+                includeSystemOps = true;
  534
+
  535
+                if (!sourceModel.HasSystemOperations())
  536
+                {
  537
+                    // upgrade scenario, inject the history model
  538
+                    _historyRepository
  539
+                        .AppendHistoryModel(
  540
+                            sourceModel,
  541
+                            new DbProviderInfo(_usersContextInfo.ConnectionProviderName, _providerManifestToken));
  542
+                }
  543
+            }
  544
+
  545
+            var systemOperations
  546
+                = _modelDiffer.Diff(sourceModel, targetModel, includeSystemOps)
  547
+                    .Where(o => o.IsSystem);
  548
+
527 549
             migration.Down();
528 550
 
529  
-            ExecuteOperations(migrationId, targetModel, migration.Operations.ToList(), downgrading: true);
  551
+            ExecuteOperations(migrationId, targetModel, migration.Operations.Concat(systemOperations), downgrading: true);
530 552
         }
531 553
 
532 554
         internal override void ApplyMigration(DbMigration migration, DbMigration lastMigration)
@@ -534,6 +556,10 @@ internal override void ApplyMigration(DbMigration migration, DbMigration lastMig
534 556
             var migrationMetadata = (IMigrationMetadata)migration;
535 557
             var compressor = new ModelCompressor();
536 558
 
  559
+            var lastModel = GetLastModel(lastMigration, migrationMetadata.Id);
  560
+            var targetModel = compressor.Decompress(Convert.FromBase64String(migrationMetadata.Target));
  561
+            var systemOperations = Enumerable.Empty<MigrationOperation>();
  562
+
537 563
             if (migrationMetadata.Source != null)
538 564
             {
539 565
                 var sourceModel
@@ -543,24 +569,62 @@ var sourceModel
543 569
                 {
544 570
                     base.AutoMigrate(
545 571
                         migrationMetadata.Id.ToAutomaticMigrationId(),
546  
-                        GetLastModel(lastMigration, migrationMetadata.Id),
  572
+                        lastModel,
547 573
                         sourceModel,
548 574
                         downgrading: false);
549 575
                 }
550 576
             }
  577
+            else
  578
+            {
  579
+                var includeSystemOps = false;
551 580
 
552  
-            migration.Up();
  581
+                if (ReferenceEquals(lastModel, _emptyModel.Value))
  582
+                {
  583
+                    includeSystemOps = true;
553 584
 
554  
-            var targetModel = compressor.Decompress(Convert.FromBase64String(migrationMetadata.Target));
  585
+                    if (!targetModel.HasSystemOperations())
  586
+                    {
  587
+                        // upgrade scenario, inject the history model
  588
+                        _historyRepository
  589
+                            .AppendHistoryModel(
  590
+                                targetModel,
  591
+                                new DbProviderInfo(_usersContextInfo.ConnectionProviderName, _providerManifestToken));
  592
+                    }
  593
+                }
  594
+
  595
+                systemOperations
  596
+                    = _modelDiffer.Diff(lastModel, targetModel, includeSystemOps)
  597
+                        .Where(o => o.IsSystem);
  598
+            }
  599
+
  600
+            migration.Up();
555 601
 
556  
-            ExecuteOperations(migrationMetadata.Id, targetModel, migration.Operations.ToList(), false);
  602
+            ExecuteOperations(migrationMetadata.Id, targetModel, migration.Operations.Concat(systemOperations), false);
557 603
         }
558 604
 
559 605
         internal override void AutoMigrate(
560 606
             string migrationId, XDocument sourceModel, XDocument targetModel, bool downgrading)
561 607
         {
  608
+            var includeSystemOps = false;
  609
+
  610
+            if (ReferenceEquals(downgrading ? targetModel : sourceModel, _emptyModel.Value))
  611
+            {
  612
+                includeSystemOps = true;
  613
+
  614
+                var appendableModel = downgrading ? sourceModel : targetModel;
  615
+
  616
+                if (!appendableModel.HasSystemOperations())
  617
+                {
  618
+                    // upgrade scenario, inject the history model
  619
+                    _historyRepository
  620
+                        .AppendHistoryModel(
  621
+                            appendableModel,
  622
+                            new DbProviderInfo(_usersContextInfo.ConnectionProviderName, _providerManifestToken));
  623
+                }
  624
+            }
  625
+
562 626
             var operations
563  
-                = _modelDiffer.Diff(sourceModel, targetModel)
  627
+                = _modelDiffer.Diff(sourceModel, targetModel, includeSystemOps)
564 628
                     .ToList();
565 629
 
566 630
             if (!_configuration.AutomaticMigrationDataLossAllowed
@@ -594,25 +658,13 @@ var orderedOperations
594 658
                     .Concat(newTableForeignKeys)
595 659
                     .ToList();
596 660
 
597  
-            var isFirstMigration = IsFirstMigration(migrationId, downgrading);
598  
-
599  
-            if (downgrading)
  661
+            if (!downgrading)
600 662
             {
601  
-                orderedOperations.Add(_historyRepository.CreateDeleteOperation(migrationId));
602  
-
603  
-                if (isFirstMigration)
604  
-                {
605  
-                    orderedOperations.Add(_historyRepository.CreateDropTableOperation(_modelDiffer));
606  
-                }
  663
+                orderedOperations.Add(_historyRepository.CreateInsertOperation(migrationId, targetModel));
607 664
             }
608  
-            else
  665
+            else if (!operations.Any(o => o.IsSystem && o is DropTableOperation))
609 666
             {
610  
-                if (isFirstMigration)
611  
-                {
612  
-                    orderedOperations.Add(_historyRepository.CreateCreateTableOperation(_modelDiffer));
613  
-                }
614  
-
615  
-                orderedOperations.Add(_historyRepository.CreateInsertOperation(migrationId, targetModel));
  667
+                orderedOperations.Add(_historyRepository.CreateDeleteOperation(migrationId));
616 668
             }
617 669
 
618 670
             var migrationStatements = SqlGenerator.Generate(orderedOperations, _providerManifestToken);
@@ -627,6 +679,11 @@ var orderedOperations
627 679
             }
628 680
 
629 681
             base.ExecuteStatements(migrationStatements);
  682
+
  683
+            if (operations.Any(o => o.IsSystem))
  684
+            {
  685
+                _historyRepository.ResetExists();
  686
+            }
630 687
         }
631 688
 
632 689
         internal override void ExecuteStatements(IEnumerable<MigrationStatement> migrationStatements)
@@ -655,6 +712,8 @@ internal override void ExecuteSql(DbTransaction transaction, MigrationStatement
655 712
                 return;
656 713
             }
657 714
 
  715
+            //Console.WriteLine(migrationStatement.Sql);
  716
+
658 717
             if (!migrationStatement.SuppressTransaction)
659 718
             {
660 719
                 using (var command = transaction.Connection.CreateCommand())
@@ -756,6 +815,7 @@ internal override void EnsureDatabaseExists()
756 815
                 if (!Database.Exists(connection))
757 816
                 {
758 817
                     new DatabaseCreator().Create(connection);
  818
+
759 819
                     _emptyMigrationNeeded = true;
760 820
                 }
761 821
                 else
@@ -770,41 +830,6 @@ internal override DbMigration GetMigration(string migrationId)
770 830
             return _migrationAssembly.GetMigration(migrationId);
771 831
         }
772 832
 
773  
-        internal override bool IsFirstMigrationIncludingAutomatics(string migrationId)
774  
-        {
775  
-            var firstMigrationId = _historyRepository.GetMigrationsSince(InitialDatabase).LastOrDefault();
776  
-
777  
-            // If this is the first applied migration, return true; otherwise false
778  
-            return firstMigrationId == null
779  
-                   || string.Equals(migrationId, firstMigrationId, StringComparison.Ordinal);
780  
-        }
781  
-
782  
-        private bool IsFirstMigration(string migrationId, bool downgrading)
783  
-        {
784  
-            Contract.Requires(!string.IsNullOrWhiteSpace(migrationId));
785  
-            Contract.Assert(migrationId.IsValidMigrationId());
786  
-
787  
-            if (downgrading)
788  
-            {
789  
-                var firstMigrationId = _historyRepository.GetMigrationsSince(InitialDatabase).LastOrDefault();
790  
-                Contract.Assert(firstMigrationId != null);
791  
-
792  
-                return string.Equals(migrationId, firstMigrationId, StringComparison.Ordinal);
793  
-            }
794  
-
795  
-            var firstExplicitMigrationId = _migrationAssembly.MigrationIds.FirstOrDefault();
796  
-
797  
-            // If this comes before or is the first explicit migration...
798  
-            if (firstExplicitMigrationId == null
799  
-                || string.Equals(migrationId, firstExplicitMigrationId, StringComparison.Ordinal)
800  
-                || string.CompareOrdinal(migrationId, firstExplicitMigrationId) < 0)
801  
-            {
802  
-                return base.IsFirstMigrationIncludingAutomatics(migrationId);
803  
-            }
804  
-
805  
-            return false;
806  
-        }
807  
-
808 833
         private DbConnection CreateConnection()
809 834
         {
810 835
             var connection = _providerFactory.CreateConnection();
15  src/EntityFramework/Migrations/Edm/EdmXNames.cs
@@ -26,6 +26,18 @@ internal static class EdmXNames
26 26
         private static readonly XNamespace _ssdlNamespaceV3
27 27
             = XNamespace.Get("http://schemas.microsoft.com/ado/2009/11/edm/ssdl");
28 28
 
  29
+        private static readonly XNamespace _annotationsNamespace
  30
+            = XNamespace.Get("http://schemas.microsoft.com/ado/2009/02/edm/annotation");
  31
+
  32
+        public static readonly XName IsSystem = _annotationsNamespace + "IsSystem";
  33
+
  34
+        public static string IsSystemAttribute(this XElement element)
  35
+        {
  36
+            Contract.Requires(element != null);
  37
+
  38
+            return (string)element.Attribute(IsSystem);
  39
+        }
  40
+
29 41
         public static string ActionAttribute(this XElement element)
30 42
         {
31 43
             Contract.Requires(element != null);
@@ -215,6 +227,8 @@ public static class Msl
215 227
 
216 228
             public static readonly IEnumerable<XName> ComplexPropertyNames = Names("ComplexProperty");
217 229
             public static readonly IEnumerable<XName> ConditionNames = Names("Condition");
  230
+            public static readonly IEnumerable<XName> EntityContainerMappingNames = Names("EntityContainerMapping");
  231
+            public static readonly IEnumerable<XName> EntitySetMappingNames = Names("EntitySetMapping");
218 232
             public static readonly IEnumerable<XName> EntityTypeMappingNames = Names("EntityTypeMapping");
219 233
 
220 234
             [SuppressMessage("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
@@ -240,6 +254,7 @@ public static class Ssdl
240 254
             public static readonly IEnumerable<XName> AssociationNames = Names("Association");
241 255
             public static readonly IEnumerable<XName> DependentNames = Names("Dependent");
242 256
             public static readonly IEnumerable<XName> EndNames = Names("End");
  257
+            public static readonly IEnumerable<XName> EntityContainerNames = Names("EntityContainer");
243 258
             public static readonly IEnumerable<XName> EntitySetNames = Names("EntitySet");
244 259
             public static readonly IEnumerable<XName> EntityTypeNames = Names("EntityType");
245 260
             public static readonly IEnumerable<XName> KeyNames = Names("Key");
129  src/EntityFramework/Migrations/History/HistoryRepository.cs
@@ -8,6 +8,7 @@ namespace System.Data.Entity.Migrations.History
8 8
     using System.Data.Entity.Infrastructure;
9 9
     using System.Data.Entity.Internal;
10 10
     using System.Data.Entity.Migrations.Edm;
  11
+    using System.Data.Entity.Migrations.Extensions;
11 12
     using System.Data.Entity.Migrations.Infrastructure;
12 13
     using System.Data.Entity.Migrations.Model;
13 14
     using System.Data.Entity.Migrations.Utilities;
@@ -22,14 +23,11 @@ namespace System.Data.Entity.Migrations.History
22 23
 
23 24
     internal class HistoryRepository : RepositoryBase
24 25
     {
25  
-        private readonly string _defaultSchema;
26  
-
27 26
         private bool? _exists;
28 27
 
29  
-        public HistoryRepository(string connectionString, DbProviderFactory providerFactory, string defaultSchema = null)
  28
+        public HistoryRepository(string connectionString, DbProviderFactory providerFactory)
30 29
             : base(connectionString, providerFactory)
31 30
         {
32  
-            _defaultSchema = defaultSchema;
33 31
         }
34 32
 
35 33
         public virtual XDocument GetLastModel()
@@ -54,10 +52,10 @@ var lastModel
54 52
                         .OrderByDescending(h => h.MigrationId)
55 53
                         .Select(
56 54
                             s => new
57  
-                                {
58  
-                                    s.MigrationId,
59  
-                                    s.Model
60  
-                                })
  55
+                                     {
  56
+                                         s.MigrationId,
  57
+                                         s.Model
  58
+                                     })
61 59
                         .FirstOrDefault();
62 60
 
63 61
                 if (lastModel == null)
@@ -259,70 +257,13 @@ public virtual IEnumerable<MigrationOperation> GetUpgradeOperations()
259 257
             return null;
260 258
         }
261 259
 
262  
-        public virtual MigrationOperation CreateCreateTableOperation(EdmModelDiffer modelDiffer)
263  
-        {
264  
-            return CreateCreateTableOperation(CreateContext, modelDiffer);
265  
-        }
266  
-
267  
-        public virtual MigrationOperation CreateCreateTableOperation<TContext>(
268  
-            Func<DbConnection, HistoryContextBase<TContext>> createContext, EdmModelDiffer modelDiffer)
269  
-            where TContext : DbContext
270  
-        {
271  
-            Contract.Requires(modelDiffer != null);
272  
-
273  
-            // force re-query on next access if we are potentially creating the table
274  
-            _exists = null;
275  
-
276  
-            using (var connection = CreateConnection())
277  
-            {
278  
-                using (var context = createContext(connection))
279  
-                {
280  
-                    using (var emptyContext = new EmptyContext(connection))
281  
-                    {
282  
-                        var operations
283  
-                            = modelDiffer.Diff(emptyContext.GetModel(), context.GetModel());
284  
-
285  
-                        var createTableOperation = operations.OfType<CreateTableOperation>().Single();
286  
-
287  
-                        createTableOperation.AnonymousArguments.Add("IsMSShipped", true);
288  
-
289  
-                        return createTableOperation;
290  
-                    }
291  
-                }
292  
-            }
293  
-        }
294  
-
295  
-        public virtual MigrationOperation CreateDropTableOperation(EdmModelDiffer modelDiffer)
296  
-        {
297  
-            Contract.Requires(modelDiffer != null);
298  
-
299  
-            // force re-query on next access if we are potentially dropping the table
300  
-            _exists = null;
301  
-
302  
-            using (var connection = CreateConnection())
303  
-            {
304  
-                using (var context = CreateContext(connection))
305  
-                {
306  
-                    using (var emptyContext = new EmptyContext(connection))
307  
-                    {
308  
-                        var operations
309  
-                            = modelDiffer.Diff(context.GetModel(), emptyContext.GetModel());
310  
-
311  
-                        var dropTableOperation = operations.OfType<DropTableOperation>().Single();
312  
-
313  
-                        return dropTableOperation;
314  
-                    }
315  
-                }
316  
-            }
317  
-        }
318  
-
319 260
         public virtual MigrationOperation CreateInsertOperation(string migrationId, XDocument model)
320 261
         {
321 262
             Contract.Requires(!string.IsNullOrWhiteSpace(migrationId));
322 263
             Contract.Requires(model != null);
323 264
 
324 265
             // TODO: Can we somehow use DbInsertCommandTree?
325  
-            return new InsertHistoryOperation(TableName, migrationId, new ModelCompressor().Compress(model));
  266
+            return new InsertHistoryOperation(HistoryContext.TableName, migrationId, new ModelCompressor().Compress(model));
326 267
         }
327 268
 
328 269
         public virtual MigrationOperation CreateDeleteOperation(string migrationId)
@@ -330,17 +271,7 @@ public virtual MigrationOperation CreateDeleteOperation(string migrationId)
330 271
             Contract.Requires(!string.IsNullOrWhiteSpace(migrationId));
331 272
 
332 273
             // TODO: Can we somehow use DbInsertCommandTree?
333  
-            return new DeleteHistoryOperation(TableName, migrationId);
334  
-        }
335  
-
336  
-        private string TableName
337  
-        {
338  
-            get
339  
-            {
340  
-                return !string.IsNullOrWhiteSpace(_defaultSchema)
341  
-                           ? _defaultSchema + "." + HistoryContext.TableName
342  
-                           : HistoryContext.TableName;
343  
-            }
  274
+            return new DeleteHistoryOperation(HistoryContext.TableName, migrationId);
344 275
         }
345 276
 
346 277
         public virtual void BootstrapUsingEFProviderDdl(XDocument model)
@@ -364,6 +295,11 @@ public virtual void BootstrapUsingEFProviderDdl(XDocument model)
364 295
             }
365 296
         }
366 297
 
  298
+        public virtual void ResetExists()
  299
+        {
  300
+            _exists = null;
  301
+        }
  302
+
367 303
         private static bool QueryExists<TContext>(HistoryContextBase<TContext> context) where TContext : DbContext
368 304
         {
369 305
             Contract.Requires(context != null);
@@ -392,7 +328,44 @@ public virtual void BootstrapUsingEFProviderDdl(XDocument model)
392 328
 
393 329
         private HistoryContext CreateContext(DbConnection connection = null)
394 330
         {
395  
-            return new HistoryContext(connection ?? CreateConnection(), connection == null, _defaultSchema);
  331
+            return new HistoryContext(connection ?? CreateConnection(), connection == null, null);
  332
+        }
  333
+
  334
+        public virtual void AppendHistoryModel(XDocument model, DbProviderInfo providerInfo)
  335
+        {
  336
+            Contract.Requires(model != null);
  337
+            Contract.Requires(providerInfo != null);
  338
+
  339
+            var csdlNamespace = model.Descendants(EdmXNames.Csdl.SchemaNames).Single().Name.Namespace;
  340
+            var mslNamespace = model.Descendants(EdmXNames.Msl.MappingNames).Single().Name.Namespace;
  341
+            var ssdlNamespace = model.Descendants(EdmXNames.Ssdl.SchemaNames).Single().Name.Namespace;
  342
+
  343
+            using (var context = CreateContext())
  344
+            {
  345
+                // prevent having to lookup the provider info.
  346
+                context.InternalContext.ModelProviderInfo = providerInfo;
  347
+
  348
+                var historyModel = context.GetModel();
  349
+
  350
+                var entityType = historyModel.Descendants(EdmXNames.Csdl.EntityTypeNames).Single();
  351
+                var entitySetMapping = historyModel.Descendants(EdmXNames.Msl.EntitySetMappingNames).Single();
  352
+                var storeEntityType = historyModel.Descendants(EdmXNames.Ssdl.EntityTypeNames).Single();
  353
+                var storeEntitySet = historyModel.Descendants(EdmXNames.Ssdl.EntitySetNames).Single();
  354
+
  355
+                new[] { entityType, entitySetMapping, storeEntityType, storeEntitySet }
  356
+                    .Each(x => x.SetAttributeValue(EdmXNames.IsSystem, true));
  357
+
  358
+                // normalize namespaces
  359
+                entityType.DescendantsAndSelf().Each(e => e.Name = csdlNamespace + e.Name.LocalName);
  360
+                entitySetMapping.DescendantsAndSelf().Each(e => e.Name = mslNamespace + e.Name.LocalName);
  361
+                storeEntityType.DescendantsAndSelf().Each(e => e.Name = ssdlNamespace + e.Name.LocalName);
  362
+                storeEntitySet.DescendantsAndSelf().Each(e => e.Name = ssdlNamespace + e.Name.LocalName);
  363
+
  364
+                model.Descendants(EdmXNames.Csdl.SchemaNames).Single().Add(entityType);
  365
+                model.Descendants(EdmXNames.Msl.EntityContainerMappingNames).Single().Add(entitySetMapping);
  366
+                model.Descendants(EdmXNames.Ssdl.SchemaNames).Single().Add(storeEntityType);
  367
+                model.Descendants(EdmXNames.Ssdl.EntityContainerNames).Single().Add(storeEntitySet);
  368
+            }
396 369
         }
397 370
     }
398 371
 }
159  src/EntityFramework/Migrations/Infrastructure/EdmModelDiffer.cs
@@ -21,14 +21,14 @@ internal class EdmModelDiffer
21 21
     {
22 22
         private static readonly PrimitiveTypeKind[] _validIdentityTypes
23 23
             = new[]
24  
-                {
25  
-                    PrimitiveTypeKind.Byte,
26  
-                    PrimitiveTypeKind.Decimal,
27  
-                    PrimitiveTypeKind.Guid,
28  
-                    PrimitiveTypeKind.Int16,
29  
-                    PrimitiveTypeKind.Int32,
30  
-                    PrimitiveTypeKind.Int64
31  
-                };
  24
+                  {
  25
+                      PrimitiveTypeKind.Byte,
  26
+                      PrimitiveTypeKind.Decimal,
  27
+                      PrimitiveTypeKind.Guid,
  28
+                      PrimitiveTypeKind.Int16,
  29
+                      PrimitiveTypeKind.Int32,
  30
+                      PrimitiveTypeKind.Int64
  31
+                  };
32 32
 
33 33
         private class ModelMetadata
34 34
         {
@@ -43,33 +43,32 @@ private class ModelMetadata
43 43
 
44 44
         private bool _consistentProviders;
45 45
 
46  
-        public IEnumerable<MigrationOperation> Diff(XDocument sourceModel, XDocument targetModel)
  46
+        public IEnumerable<MigrationOperation> Diff(XDocument sourceModel, XDocument targetModel, bool includeSystemOperations = false)
47 47
         {
48 48
             DbProviderInfo providerInfo;
49 49
 
50 50
             _source
51 51
                 = new ModelMetadata
52  
-                    {
53  
-                        Model = sourceModel,
54  
-                        StoreItemCollection = sourceModel.GetStoreItemCollection(out providerInfo),
55  
-                        ProviderManifest = GetProviderManifest(providerInfo),
56  
-                        ProviderInfo = providerInfo
57  
-                    };
  52
+                      {
  53
+                          Model = sourceModel,
  54
+                          StoreItemCollection = sourceModel.GetStoreItemCollection(out providerInfo),
  55
+                          ProviderManifest = GetProviderManifest(providerInfo),
  56
+                          ProviderInfo = providerInfo
  57
+                      };
58 58
 
59 59
             _target
60 60
                 = new ModelMetadata
61  
-                    {
62  
-                        Model = targetModel,
63  
-                        StoreItemCollection = targetModel.GetStoreItemCollection(out providerInfo),
64  
-                        ProviderManifest = GetProviderManifest(providerInfo),
65  
-                        ProviderInfo = providerInfo
66  
-                    };
  61
+                      {
  62
+                          Model = targetModel,
  63
+                          StoreItemCollection = targetModel.GetStoreItemCollection(out providerInfo),
  64
+                          ProviderManifest = GetProviderManifest(providerInfo),
  65
+                          ProviderInfo = providerInfo
  66
+                      };
67 67
 
68 68
             _consistentProviders
69 69
                 = _source.ProviderInfo.ProviderInvariantName.EqualsIgnoreCase(
70 70
                     _target.ProviderInfo.ProviderInvariantName)
71  
-                  &&
72  
-                  _source.ProviderInfo.ProviderManifestToken.EqualsIgnoreCase(
  71
+                  && _source.ProviderInfo.ProviderManifestToken.EqualsIgnoreCase(
73 72
                       _target.ProviderInfo.ProviderManifestToken);
74 73
 
75 74
             var renamedColumns = FindRenamedColumns().ToList();
@@ -99,7 +98,9 @@ public IEnumerable<MigrationOperation> Diff(XDocument sourceModel, XDocument tar
99 98
                 .Concat(addedForeignKeys)
100 99
                 .Concat(addedForeignKeys.Select(fko => fko.CreateCreateIndexOperation()))
101 100
                 .Concat(removedColumns)
102  
-                .Concat(removedTables).ToList();
  101
+                .Concat(removedTables)
  102
+                .Where(o => includeSystemOperations || !o.IsSystem)
  103
+                .ToList();
103 104
         }
104 105
 
105 106
         private XDocument BuildColumnNormalizedSourceModel(IEnumerable<RenameColumnOperation> renamedColumns)
@@ -162,7 +163,8 @@ private IEnumerable<CreateTableOperation> FindAddedTables(IEnumerable<RenameTabl
162 163
                 .Where(es => !renamedTables.Any(rt => rt.NewName.EqualsIgnoreCase(es.TableAttribute())))
163 164
                 .Select(
164 165
                     es =>
165  
-                    BuildCreateTableOperation(es.NameAttribute(), es.TableAttribute(), es.SchemaAttribute(), _target));
  166
+                    BuildCreateTableOperation(
  167
+                        es.NameAttribute(), es.TableAttribute(), es.SchemaAttribute(), es.IsSystemAttribute(), _target));
166 168
         }
167 169
 
168 170
         private IEnumerable<MoveTableOperation> FindMovedTables()
@@ -190,7 +192,11 @@ private IEnumerable<DropTableOperation> FindRemovedTables(IEnumerable<RenameTabl
190 192
                                   es.NameAttribute(),
191 193
                                   es.TableAttribute(),
192 194
                                   es.SchemaAttribute(),
193  
-                                  _source)));
  195
+                                  es.IsSystemAttribute(),
  196
+                                  _source))
  197
+                              {
  198
+                                  IsSystem = es.IsSystemAttribute().EqualsIgnoreCase("true")
  199
+                              });
194 200
         }
195 201
 
196 202
         private IEnumerable<DropColumnOperation> FindRemovedColumns(IEnumerable<RenameColumnOperation> renamedColumns)
@@ -290,17 +296,17 @@ where a1.NameAttribute().EqualsIgnoreCase(a2.NameAttribute())
290 296
                    from n1 in d1.Descendants(EdmXNames.Ssdl.PropertyRefNames)
291 297
                        .Select(x => x.NameAttribute()).Select(
292 298
                            (name, index) => new
293  
-                               {
294  
-                                   name,
295  
-                                   index
296  
-                               })
  299
+                                                {
  300
+                                                    name,
  301
+                                                    index
  302
+                                                })
297 303
                    from n2 in d2.Descendants(EdmXNames.Ssdl.PropertyRefNames)
298 304
                        .Select(x => x.NameAttribute()).Select(
299 305
                            (name, index) => new
300  
-                               {
301  
-                                   name,
302  
-                                   index
303  
-                               })
  306
+                                                {
  307
+                                                    name,
  308
+                                                    index
  309
+                                                })
304 310
                    where (n1.index == n2.index)
305 311
                          && !n1.name.EqualsIgnoreCase(n2.name)
306 312
                    let t = GetQualifiedTableName(_target.Model, d2.RoleAttribute())
@@ -373,6 +379,13 @@ private bool DiffColumns(XElement column1, XElement column2)
373 379
             c1.SetAttributeValue("Type", null);
374 380
             c2.SetAttributeValue("Type", null);
375 381
 
  382
+            if (((c1.MaxLengthAttribute() != null) && (c2.MaxLengthAttribute() == null))
  383
+                || ((c1.MaxLengthAttribute() == null) && (c2.MaxLengthAttribute() != null)))
  384
+            {
  385
+                c1.SetAttributeValue("MaxLength", null);
  386
+                c2.SetAttributeValue("MaxLength", null);
  387
+            }
  388
+
376 389
             return CanonicalDeepEquals(c1, c2);
377 390
         }
378 391
 
@@ -466,9 +479,9 @@ where et1.NameAttribute().EqualsIgnoreCase(et2.NameAttribute())
466 479
             string oldTable, string newTable, XElement oldKey, XElement newKey)
467 480
         {
468 481
             var dropPrimaryKeyOperation = new DropPrimaryKeyOperation
469  
-                {
470  
-                    Table = oldTable
471  
-                };
  482
+                                              {
  483
+                                                  Table = oldTable
  484
+                                              };
472 485
 
473 486
             oldKey.Descendants(EdmXNames.Ssdl.PropertyRefNames).Each(
474 487
                 pr => dropPrimaryKeyOperation.Columns.Add(pr.NameAttribute()));
@@ -476,9 +489,9 @@ where et1.NameAttribute().EqualsIgnoreCase(et2.NameAttribute())
476 489
             yield return dropPrimaryKeyOperation;
477 490
 
478 491
             var addPrimaryKeyOperation = new AddPrimaryKeyOperation
479  
-                {
480  
-                    Table = newTable
481  
-                };
  492
+                                             {
  493
+                                                 Table = newTable
  494
+                                             };
482 495
 
483 496
             newKey.Descendants(EdmXNames.Ssdl.PropertyRefNames).Each(
484 497
                 pr => addPrimaryKeyOperation.Columns.Add(pr.NameAttribute()));
@@ -513,6 +526,7 @@ private static bool DiffAssociations(XElement a1, XElement a2)
513 526
             string entitySetName,
514 527
             string tableName,
515 528
             string schema,
  529
+            string isSystem,
516 530
             ModelMetadata modelMetadata)
517 531
         {
518 532
             Contract.Requires(!string.IsNullOrWhiteSpace(entitySetName));
@@ -536,6 +550,7 @@ private static bool DiffAssociations(XElement a1, XElement a2)
536 550
                 .Each(pr => addPrimaryKeyOperation.Columns.Add(pr.NameAttribute()));
537 551
 
538 552
             createTableOperation.PrimaryKey = addPrimaryKeyOperation;
  553
+            createTableOperation.IsSystem = isSystem.EqualsIgnoreCase("true");
539 554
 
540 555
             return createTableOperation;
541 556
         }
@@ -569,30 +584,30 @@ var edmProperty
569 584
 
570 585
             var column
571 586
                 = new ColumnModel(((PrimitiveType)edmProperty.TypeUsage.EdmType).PrimitiveTypeKind, typeUsage)
572  
-                    {
573  
-                        Name = nameAttribute,
574  
-                        IsNullable
575  
-                            = !string.IsNullOrWhiteSpace(nullableAttribute)
576  
-                              && !Convert.ToBoolean(nullableAttribute, CultureInfo.InvariantCulture)
577  
-                                  ? false
578  
-                                  : (bool?)null,
579  
-                        MaxLength
580  
-                            = !string.IsNullOrWhiteSpace(maxLengthAttribute)
581  
-                                  ? Convert.ToInt32(maxLengthAttribute, CultureInfo.InvariantCulture)
582  
-                                  : (int?)null,
583  
-                        Precision
584  
-                            = !string.IsNullOrWhiteSpace(precisionAttribute)
585  
-                                  ? Convert.ToByte(precisionAttribute, CultureInfo.InvariantCulture)
586  
-                                  : (byte?)null,
587  
-                        Scale
588  
-                            = !string.IsNullOrWhiteSpace(scaleAttribute)
589  
-                                  ? Convert.ToByte(scaleAttribute, CultureInfo.InvariantCulture)
590  
-                                  : (byte?)null,
591  
-                        StoreType
592  
-                            = !storeType.EqualsIgnoreCase(defaultStoreTypeName)
593  
-                                  ? storeType
594  
-                                  : null
595  
-                    };
  587
+                      {
  588
+                          Name = nameAttribute,
  589
+                          IsNullable
  590
+                              = !string.IsNullOrWhiteSpace(nullableAttribute)
  591
+                                && !Convert.ToBoolean(nullableAttribute, CultureInfo.InvariantCulture)
  592
+                                    ? false
  593
+                                    : (bool?)null,
  594
+                          MaxLength
  595
+                              = !string.IsNullOrWhiteSpace(maxLengthAttribute)
  596
+                                    ? Convert.ToInt32(maxLengthAttribute, CultureInfo.InvariantCulture)
  597
+                                    : (int?)null,
  598
+                          Precision
  599
+                              = !string.IsNullOrWhiteSpace(precisionAttribute)
  600
+                                    ? Convert.ToByte(precisionAttribute, CultureInfo.InvariantCulture)
  601
+                                    : (byte?)null,
  602
+                          Scale
  603
+                              = !string.IsNullOrWhiteSpace(scaleAttribute)
  604
+                                    ? Convert.ToByte(scaleAttribute, CultureInfo.InvariantCulture)
  605
+                                    : (byte?)null,
  606
+                          StoreType
  607
+                              = !storeType.EqualsIgnoreCase(defaultStoreTypeName)
  608
+                                    ? storeType
  609
+                                    : null
  610
+                      };
596 611
 
597 612
             column.IsIdentity
598 613
                 = !string.IsNullOrWhiteSpace(storeGeneratedPatternAttribute)
@@ -719,10 +734,10 @@ var schemaAndTable
719 734
                 = (from es in model.Descendants(EdmXNames.Ssdl.EntitySetNames)
720 735
                    where es.NameAttribute().EqualsIgnoreCase(entitySetName)
721 736
                    select new
722  
-                       {
723  
-                           Schema = es.SchemaAttribute(),
724  
-                           Table = es.TableAttribute()
725  
-                       })
  737
+                              {
  738
+                                  Schema = es.SchemaAttribute(),
  739
+                                  Table = es.TableAttribute()
  740
+                              })
726 741
                     .Single();
727 742
 
728 743
             return GetQualifiedTableName(schemaAndTable.Table, schemaAndTable.Schema);
@@ -737,10 +752,10 @@ var schemaAndTable
737 752
                 = (from es in model.Descendants(EdmXNames.Ssdl.EntitySetNames)
738 753
                    where es.EntityTypeAttribute().EqualsIgnoreCase(entityTypeName)
739 754
                    select new
740  
-                       {
741  
-                           Schema = es.SchemaAttribute(),
742  
-                           Table = es.TableAttribute()
743  
-                       })
  755
+                              {
  756
+                                  Schema = es.SchemaAttribute(),
  757
+                                  Table = es.TableAttribute()
  758
+                              })
744 759
                     .Single();
745 760
 
746 761
             return GetQualifiedTableName(schemaAndTable.Table, schemaAndTable.Schema);
12  src/EntityFramework/Migrations/Infrastructure/MigratorBase.cs
@@ -128,13 +128,14 @@ internal virtual void EnsureDatabaseExists()
128 128
             _this.EnsureDatabaseExists();
129 129
         }
130 130
 
131  
-        internal virtual void RevertMigration(string migrationId, DbMigration migration, XDocument targetModel)
  131
+        internal virtual void RevertMigration(string migrationId, DbMigration migration, XDocument sourceModel, XDocument targetModel)
132 132
         {
133 133
             Contract.Requires(!string.IsNullOrWhiteSpace(migrationId));
134 134
             Contract.Requires(migration != null);
  135
+            Contract.Requires(sourceModel != null);
135 136
             Contract.Requires(targetModel != null);
136 137
 
137  
-            _this.RevertMigration(migrationId, migration, targetModel);
  138
+            _this.RevertMigration(migrationId, migration, sourceModel, targetModel);
138 139
         }
139 140
 
140 141
         internal virtual void SeedDatabase()
@@ -187,13 +188,6 @@ internal virtual DbMigration GetMigration(string migrationId)
187 188
             return _this.GetMigration(migrationId);
188 189
         }
189 190
 
190  
-        internal virtual bool IsFirstMigrationIncludingAutomatics(string migrationId)
191  
-        {
192  
-            Contract.Requires(!string.IsNullOrWhiteSpace(migrationId));
193  
-
194  
-            return _this.IsFirstMigrationIncludingAutomatics(migrationId);
195  
-        }
196  
-
197 191
         internal virtual string TargetDatabase
198 192
         {
199 193
             get { return _this.TargetDatabase; }
4  src/EntityFramework/Migrations/Infrastructure/MigratorLoggingDecorator.cs
@@ -113,11 +113,11 @@ internal override void ApplyMigration(DbMigration migration, DbMigration lastMig
113 113
             base.ApplyMigration(migration, lastMigration);
114 114
         }
115 115
 
116  
-        internal override void RevertMigration(string migrationId, DbMigration migration, XDocument targetModel)
  116
+        internal override void RevertMigration(string migrationId, DbMigration migration, XDocument soureModel, XDocument targetModel)
117 117
         {
118 118
             _logger.Info(Strings.LoggingRevertMigration(migrationId));
119 119
 
120  
-            base.RevertMigration(migrationId, migration, targetModel);
  120
+            base.RevertMigration(migrationId, migration, soureModel, targetModel);
121 121
         }
122 122
 
123 123
         internal override void SeedDatabase()
13  src/EntityFramework/Migrations/Infrastructure/MigratorScriptingDecorator.cs
@@ -102,18 +102,5 @@ internal override void ExecuteStatements(IEnumerable<MigrationStatement> migrati
102 102
         internal override void SeedDatabase()
103 103
         {
104 104
         }
105  
-
106  
-        internal override bool IsFirstMigrationIncludingAutomatics(string migrationId)
107  
-        {
108  
-            if (migrationId.IsAutomaticMigration())
109  
-            {
110  
-                return true;
111  
-            }
112  
-
113  
-            var migration = base.GetMigration(migrationId);
114  
-            var migrationMetadata = (IMigrationMetadata)migration;
115  
-
116  
-            return (migrationMetadata.Source == null);
117  
-        }
118 105
     }
119 106
 }
2  src/EntityFramework/Migrations/Model/MigrationOperation.cs
@@ -48,5 +48,7 @@ public virtual MigrationOperation Inverse
48 48
         ///     Gets a value indicating if this operation may result in data loss.
49 49
         /// </summary>
50 50
         public abstract bool IsDestructiveChange { get; }
  51
+
  52
+        internal bool IsSystem { get; set; }
51 53
     }
52 54
 }
6  src/EntityFramework/Migrations/Sql/SqlServerMigrationSqlGenerator.cs
@@ -146,11 +146,7 @@ protected virtual void GenerateMakeSystemTable(CreateTableOperation createTableO
146 146
         {
147 147
             Contract.Requires(createTableOperation != null);
148 148
 
149  
-            object isMsShippedValue;
150  
-            createTableOperation.AnonymousArguments.TryGetValue("IsMSShipped", out isMsShippedValue);
151  
-            var isMsShipped = isMsShippedValue as bool?;
152  
-
153  
-            if (isMsShipped == true)
  149
+            if (createTableOperation.IsSystem)
154 150
             {
155 151
                 using (var writer = Writer())
156 152
                 {
9  src/EntityFramework/Utilities/DbContextExtensions.cs
@@ -18,15 +18,8 @@ public static XDocument GetModel(this DbContext context)
18 18
             return GetModel(w => EdmxWriter.WriteEdmx(context, w));
19 19
         }
20 20
 
21  
-        public static XDocument GetModel(this DbModel model)
22  
-        {
23  
-            Contract.Requires(model != null);
24  
-
25  
-            return GetModel(w => EdmxWriter.WriteEdmx(model, w));
26  
-        }
27  
-
28 21
         [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times")]
29  
-        private static XDocument GetModel(Action<XmlWriter> writeXml)
  22
+        public static XDocument GetModel(Action<XmlWriter> writeXml)
30 23
         {
31 24
             Contract.Requires(writeXml != null);
32 25
 
18  src/EntityFramework/Utilities/DbModelExtensions.cs
... ...
@@ -0,0 +1,18 @@
  1
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
  2
+
  3
+namespace System.Data.Entity.Utilities
  4
+{
  5
+    using System.Data.Entity.Infrastructure;
  6
+    using System.Diagnostics.Contracts;
  7
+    using System.Xml.Linq;
  8
+
  9
+    internal static class DbModelExtensions
  10
+    {
  11
+        public static XDocument GetModel(this DbModel model)
  12
+        {
  13
+            Contract.Requires(model != null);
  14
+
  15
+            return DbContextExtensions.GetModel(w => EdmxWriter.WriteEdmx(model, w));
  16
+        }
  17
+    }
  18
+}
7  src/EntityFramework/Utilities/XDocumentExtensions.cs
@@ -22,5 +22,12 @@ public static StoreItemCollection GetStoreItemCollection(this XDocument model, o
22 22
 
23 23
             return new StoreItemCollection(new[] { schemaElement.CreateReader() });
24 24
         }
  25
+
  26
+        public static bool HasSystemOperations(this XDocument model)
  27
+        {
  28
+            Contract.Requires(model != null);
  29
+
  30
+            return model.Descendants().Attributes(EdmXNames.IsSystem).Any();
  31
+        }
25 32
     }
26 33
 }
2  test/EntityFramework/FunctionalTests/FunctionalTests.csproj
@@ -159,6 +159,7 @@
159 159
     <Compile Include="Migrations\AutoAndGenerateScenarios.cs" />
160 160
     <Compile Include="Migrations\AutoAndGenerateTestCase.cs" />
161 161
     <Compile Include="Migrations\BasicMigrationScenarios.cs" />
  162
+    <Compile Include="Migrations\UpgradeScenarios.cs" />
162 163
     <Compile Include="Migrations\SchemaScenarios.cs" />
163 164
     <Compile Include="Migrations\CreateIndexScenarios.cs" />
164 165
     <Compile Include="Migrations\CreateTableScenarios.cs" />
@@ -592,7 +593,6 @@
592 593
     <Compile Include="TestHelpers\ConnectionEventsTracker.cs" />
593 594
     <Compile Include="TestHelpers\ConstructionStrategies.cs" />
594 595
     <Compile Include="TestHelpers\DbContextExtensions.cs" />
595  
-    <Compile Include="TestHelpers\DbModelExtensions.cs" />
596 596
     <Compile Include="TestHelpers\EntityTypeConfigurationExtensions.cs" />
597 597
     <Compile Include="TestHelpers\ExceptionTestExtensions.cs" />
598 598
     <Compile Include="TestHelpers\ExceptionHelpers.cs" />
4  test/EntityFramework/FunctionalTests/Migrations/DashScriptScenarios.cs
@@ -260,12 +260,10 @@ public void Can_script_downs()
260 260
 
261 261
             var scriptingDecorator = new MigratorScriptingDecorator(migrator);
262 262
 
263  
-            // Act
264 263
             var script = scriptingDecorator.ScriptUpdate(null, DbMigrator.InitialDatabase);
265 264
 
266  
-            // Assert
267 265
             Assert.True(script.Contains(DropMetadataStatement));
268  
-            Assert.True(script.Contains("Version1"));
  266
+            Assert.False(script.Contains("Version1"));
269 267
         }
270 268
 
271 269
         [MigrationsTheory]
74  test/EntityFramework/FunctionalTests/Migrations/SchemaScenarios.cs
... ...
@@ -1,83 +1,11 @@
1 1
 // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
  2
+
2 3
 namespace System.Data.Entity.Migrations
3 4
 {
4  
-    using System.Data.Entity.Migrations.Design;
5  
-    using System.Data.Entity.Migrations.History;
6  
-    using Xunit;
7  
-
8 5
     [Variant(DatabaseProvider.SqlClient, ProgrammingLanguage.CSharp)]
9 6
     [Variant(DatabaseProvider.SqlServerCe, ProgrammingLanguage.CSharp)]
10 7
     [Variant(DatabaseProvider.SqlClient, ProgrammingLanguage.VB)]
11 8
     public class SchemaScenarios : DbTestCase
12 9
     {
13  
-        private class CustomSchemaContext : ShopContext_v1
14  
-        {
15  
-            protected override void OnModelCreating(DbModelBuilder modelBuilder)
16  
-            {
17  
-                base.OnModelCreating(modelBuilder);
18  
-
19  
-                modelBuilder.HasDefaultSchema("foo");
20  
-            }
21  
-        }
22  
-
23  
-        [MigrationsTheory]
24  
-        public void Can_update_when_custom_default_schema()
25  
-        {
26  
-            DropDatabase();
27  
-
28  
-            var migrator = CreateMigrator<CustomSchemaContext>();