From 20372c59ff9ee3984c3d5d5da4b25a6837878dc2 Mon Sep 17 00:00:00 2001 From: Justin Baur <19896123+justindbaur@users.noreply.github.com> Date: Fri, 30 Jun 2023 09:13:38 -0400 Subject: [PATCH 1/2] Add `migrations has-pending-model-changes` Command - Add command - Add DatabaseFacade extension method --- .../Design/Internal/MigrationsOperations.cs | 21 +++++ src/EFCore.Design/Design/OperationExecutor.cs | 34 ++++++++ .../Properties/DesignStrings.Designer.cs | 12 +++ .../Properties/DesignStrings.resx | 6 ++ .../RelationalDatabaseFacadeExtensions.cs | 33 +++++++ .../Properties/Resources.Designer.cs | 7 ++ src/dotnet-ef/Properties/Resources.resx | 5 +- src/ef/Commands/MigrationsCommand.cs | 1 + ...HasPendingModelChangesCommand.Configure.cs | 17 ++++ ...MigrationsHasPendingModelChangesCommand.cs | 16 ++++ src/ef/IOperationExecutor.cs | 1 + src/ef/OperationExecutorBase.cs | 5 ++ src/ef/Properties/Resources.Designer.cs | 7 ++ src/ef/Properties/Resources.resx | 5 +- .../RelationalDatabaseFacadeExtensionsTest.cs | 86 ++++++++++++++++++- 15 files changed, 253 insertions(+), 3 deletions(-) create mode 100644 src/ef/Commands/MigrationsHasPendingModelChangesCommand.Configure.cs create mode 100644 src/ef/Commands/MigrationsHasPendingModelChangesCommand.cs diff --git a/src/EFCore.Design/Design/Internal/MigrationsOperations.cs b/src/EFCore.Design/Design/Internal/MigrationsOperations.cs index 294f1d29723..3f105e7ba87 100644 --- a/src/EFCore.Design/Design/Internal/MigrationsOperations.cs +++ b/src/EFCore.Design/Design/Internal/MigrationsOperations.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.EntityFrameworkCore.Internal; +using Microsoft.EntityFrameworkCore.Migrations.Internal; namespace Microsoft.EntityFrameworkCore.Design.Internal; @@ -242,6 +243,26 @@ public virtual MigrationFiles RemoveMigration( return files; } + /// + /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to + /// the same compatibility standards as public APIs. It may be changed or removed without notice in + /// any release. You should only use it directly in your code with extreme caution and knowing that + /// doing so can result in application failures when updating to a new Entity Framework Core release. + /// + public virtual void CheckPendingMigrations(string? contextType) + { + using var context = _contextOperations.CreateContext(contextType); + + var hasPendingModelChanges = context.Database.HasPendingModelChanges(); + + if (hasPendingModelChanges) + { + throw new OperationException(DesignStrings.PendingModelChanges); + } + + _reporter.WriteInformation(DesignStrings.NoPendingModelChanges); + } + private static void EnsureServices(IServiceProvider services) { var migrator = services.GetService(); diff --git a/src/EFCore.Design/Design/OperationExecutor.cs b/src/EFCore.Design/Design/OperationExecutor.cs index d08561fbfc4..715ecfe5421 100644 --- a/src/EFCore.Design/Design/OperationExecutor.cs +++ b/src/EFCore.Design/Design/OperationExecutor.cs @@ -683,6 +683,40 @@ public ScriptDbContext( private string ScriptDbContextImpl(string? contextType) => ContextOperations.ScriptDbContext(contextType); + /// + /// Represents an operation to check if there are any pending migrations. + /// + public class CheckPendingMigrations : OperationBase + { + /// + /// Initializes a new instance of the class. + /// + /// + /// The arguments supported by are: + /// contextType--The to use. + /// + /// The operation executor. + /// The . + /// The operation arguments. + public CheckPendingMigrations( + OperationExecutor executor, + IOperationResultHandler resultHandler, + IDictionary args) + : base(resultHandler) + { + Check.NotNull(executor, nameof(executor)); + Check.NotNull(args, nameof(args)); + + var contextType = (string?)args["contextType"]; + + Execute(() => executor.CheckPendingMigrationsImpl(contextType)); + } + } + + private void CheckPendingMigrationsImpl(string? contextType) + => MigrationsOperations.CheckPendingMigrations(contextType); + + /// /// Represents an operation. /// diff --git a/src/EFCore.Design/Properties/DesignStrings.Designer.cs b/src/EFCore.Design/Properties/DesignStrings.Designer.cs index 815834efe07..e5cd0177402 100644 --- a/src/EFCore.Design/Properties/DesignStrings.Designer.cs +++ b/src/EFCore.Design/Properties/DesignStrings.Designer.cs @@ -551,6 +551,12 @@ public static string NonRelationalProvider(object? provider) GetString("NonRelationalProvider", nameof(provider)), provider); + /// + /// No changes have been made to the model since the last migration. + /// + public static string NoPendingModelChanges + => GetString("NoPendingModelChanges"); + /// /// No referenced design-time services were found. /// @@ -591,6 +597,12 @@ public static string NotExistDatabase(object? name) GetString("NotExistDatabase", nameof(name)), name); + /// + /// Changes have been made to the model since the last migration. Add a new migration. + /// + public static string PendingModelChanges + => GetString("PendingModelChanges"); + /// /// Prefix output with level. /// diff --git a/src/EFCore.Design/Properties/DesignStrings.resx b/src/EFCore.Design/Properties/DesignStrings.resx index 5da17b71cb6..12c829d9a5b 100644 --- a/src/EFCore.Design/Properties/DesignStrings.resx +++ b/src/EFCore.Design/Properties/DesignStrings.resx @@ -332,6 +332,9 @@ Change your target project to the migrations project by using the Package Manage The provider '{provider}' is not a Relational provider and therefore cannot be used with Migrations. + + No changes have been made to the model since the last migration. + No referenced design-time services were found. @@ -350,6 +353,9 @@ Change your target project to the migrations project by using the Package Manage Database '{name}' did not exist, no action was taken. + + Changes have been made to the model since the last migration. Add a new migration. + Prefix output with level. diff --git a/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs b/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs index dd2cc1cdb8f..694d0f7e285 100644 --- a/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs @@ -952,6 +952,39 @@ public static bool IsRelational(this DatabaseFacade databaseFacade) => ((IDatabaseFacadeDependenciesAccessor)databaseFacade) .Context.GetService().Extensions.OfType().Any(); + /// + /// Returns if the model has pending changes to be applied. + /// + /// Tbe facade from . + /// + /// if the database model has pending changes. + /// if a new migration has to be added. + /// + public static bool HasPendingModelChanges(this DatabaseFacade databaseFacade) + { + var modelDiffer = databaseFacade.GetRelationalService(); + var migrationsAssembly = databaseFacade.GetRelationalService(); + + var modelInitializer = databaseFacade.GetRelationalService(); + + var snapshotModel = migrationsAssembly.ModelSnapshot?.Model; + if (snapshotModel is IMutableModel mutableModel) + { + snapshotModel = mutableModel.FinalizeModel(); + } + + if (snapshotModel is not null) + { + snapshotModel = modelInitializer.Initialize(snapshotModel); + } + + var designTimeModel = databaseFacade.GetRelationalService(); + + return modelDiffer.HasDifferences( + snapshotModel?.GetRelationalModel(), + designTimeModel.Model.GetRelationalModel()); + } + private static IRelationalDatabaseFacadeDependencies GetFacadeDependencies(DatabaseFacade databaseFacade) { var dependencies = ((IDatabaseFacadeDependenciesAccessor)databaseFacade).Dependencies; diff --git a/src/dotnet-ef/Properties/Resources.Designer.cs b/src/dotnet-ef/Properties/Resources.Designer.cs index 25392da7117..6721009a20e 100644 --- a/src/dotnet-ef/Properties/Resources.Designer.cs +++ b/src/dotnet-ef/Properties/Resources.Designer.cs @@ -241,6 +241,12 @@ public static string MigrationsBundleRuntimeDescription public static string MigrationsDescription => GetString("MigrationsDescription"); + /// + /// Checks if any changes have been made to the model since the last migration. + /// + public static string MigrationsHasPendingModelChangesDescription + => GetString("MigrationsHasPendingModelChangesDescription"); + /// /// Lists available migrations. /// @@ -505,3 +511,4 @@ private static string GetString(string name, params string[] formatterNames) } } } + diff --git a/src/dotnet-ef/Properties/Resources.resx b/src/dotnet-ef/Properties/Resources.resx index fd52fa85898..8bfe4b57cab 100644 --- a/src/dotnet-ef/Properties/Resources.resx +++ b/src/dotnet-ef/Properties/Resources.resx @@ -228,6 +228,9 @@ Commands to manage migrations. + + Checks if any changes have been made to the model since the last migration. + Lists available migrations. @@ -345,4 +348,4 @@ Writing '{file}'... - + \ No newline at end of file diff --git a/src/ef/Commands/MigrationsCommand.cs b/src/ef/Commands/MigrationsCommand.cs index d6f44f09129..674b8c3e549 100644 --- a/src/ef/Commands/MigrationsCommand.cs +++ b/src/ef/Commands/MigrationsCommand.cs @@ -14,6 +14,7 @@ public override void Configure(CommandLineApplication command) command.Command("add", new MigrationsAddCommand().Configure); command.Command("bundle", new MigrationsBundleCommand().Configure); + command.Command("has-pending-model-changes", new MigrationsHasPendingModelChangesCommand().Configure); command.Command("list", new MigrationsListCommand().Configure); command.Command("remove", new MigrationsRemoveCommand().Configure); command.Command("script", new MigrationsScriptCommand().Configure); diff --git a/src/ef/Commands/MigrationsHasPendingModelChangesCommand.Configure.cs b/src/ef/Commands/MigrationsHasPendingModelChangesCommand.Configure.cs new file mode 100644 index 00000000000..d5b025d320a --- /dev/null +++ b/src/ef/Commands/MigrationsHasPendingModelChangesCommand.Configure.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.DotNet.Cli.CommandLine; +using Microsoft.EntityFrameworkCore.Tools.Properties; + +namespace Microsoft.EntityFrameworkCore.Tools.Commands; + +internal partial class MigrationsHasPendingModelChangesCommand : ContextCommandBase +{ + public override void Configure(CommandLineApplication command) + { + command.Description = Resources.MigrationsHasPendingModelChangesDescription; + + base.Configure(command); + } +} diff --git a/src/ef/Commands/MigrationsHasPendingModelChangesCommand.cs b/src/ef/Commands/MigrationsHasPendingModelChangesCommand.cs new file mode 100644 index 00000000000..57068b8e53e --- /dev/null +++ b/src/ef/Commands/MigrationsHasPendingModelChangesCommand.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace Microsoft.EntityFrameworkCore.Tools.Commands; + +internal partial class MigrationsHasPendingModelChangesCommand +{ + protected override int Execute(string[] args) + { + using var executor = CreateExecutor(args); + + executor.CheckPendingMigrations(Context!.Value()); + + return base.Execute(args); + } +} diff --git a/src/ef/IOperationExecutor.cs b/src/ef/IOperationExecutor.cs index 90f3e322e9d..432c2df68f5 100644 --- a/src/ef/IOperationExecutor.cs +++ b/src/ef/IOperationExecutor.cs @@ -37,4 +37,5 @@ IDictionary ScaffoldContext( string ScriptMigration(string? fromMigration, string? toMigration, bool idempotent, bool noTransactions, string? contextType); string ScriptDbContext(string? contextType); + void CheckPendingMigrations(string? contextType); } diff --git a/src/ef/OperationExecutorBase.cs b/src/ef/OperationExecutorBase.cs index 73b1e74d6b6..a4fcd85546c 100644 --- a/src/ef/OperationExecutorBase.cs +++ b/src/ef/OperationExecutorBase.cs @@ -206,4 +206,9 @@ public string ScriptDbContext(string? contextType) => InvokeOperation( "ScriptDbContext", new Dictionary { ["contextType"] = contextType }); + + public void CheckPendingMigrations(string? contextType) + => InvokeOperation( + "CheckPendingMigrations", + new Dictionary { ["contextType"] = contextType }); } diff --git a/src/ef/Properties/Resources.Designer.cs b/src/ef/Properties/Resources.Designer.cs index b96dc343edf..9ae329692c9 100644 --- a/src/ef/Properties/Resources.Designer.cs +++ b/src/ef/Properties/Resources.Designer.cs @@ -317,6 +317,12 @@ public static string MigrationsBundleRuntimeDescription public static string MigrationsDescription => GetString("MigrationsDescription"); + /// + /// Checks if any changes have been made to the model since the last migration. + /// + public static string MigrationsHasPendingModelChangesDescription + => GetString("MigrationsHasPendingModelChangesDescription"); + /// /// Lists available migrations. /// @@ -647,3 +653,4 @@ private static string GetString(string name, params string[] formatterNames) } } } + diff --git a/src/ef/Properties/Resources.resx b/src/ef/Properties/Resources.resx index 11ef663ef9e..ec632fe97ef 100644 --- a/src/ef/Properties/Resources.resx +++ b/src/ef/Properties/Resources.resx @@ -258,6 +258,9 @@ Commands to manage migrations. + + Checks if any changes have been made to the model since the last migration. + Lists available migrations. @@ -402,4 +405,4 @@ Writing '{file}'... - + \ No newline at end of file diff --git a/test/EFCore.Relational.Tests/RelationalDatabaseFacadeExtensionsTest.cs b/test/EFCore.Relational.Tests/RelationalDatabaseFacadeExtensionsTest.cs index 228fc1c45c2..dc0dcec8f1b 100644 --- a/test/EFCore.Relational.Tests/RelationalDatabaseFacadeExtensionsTest.cs +++ b/test/EFCore.Relational.Tests/RelationalDatabaseFacadeExtensionsTest.cs @@ -3,6 +3,7 @@ using System.Transactions; using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; +using Microsoft.EntityFrameworkCore.TestModels.UpdatesModel; using Microsoft.EntityFrameworkCore.TestUtilities.FakeProvider; using IsolationLevel = System.Data.IsolationLevel; @@ -220,7 +221,7 @@ public void GetMigrations_works() private class FakeIMigrationsAssembly : IMigrationsAssembly { public IReadOnlyDictionary Migrations { get; set; } - public ModelSnapshot ModelSnapshot { get; } + public ModelSnapshot ModelSnapshot { get; set; } public Assembly Assembly { get; } public string FindMigrationId(string nameOrId) @@ -249,6 +250,89 @@ public async Task GetAppliedMigrations_works(bool async) : context.Database.GetAppliedMigrations()); } + [ConditionalFact] + public void HasPendingModelChanges_has_no_migrations_has_dbcontext_changes_returns_true() + { + // This project has NO existing migrations right now but does have information in the DbContext + var migrationsAssembly = new FakeIMigrationsAssembly + { + ModelSnapshot = null, + Migrations = new Dictionary(), + }; + + var testHelper = FakeRelationalTestHelpers.Instance; + + var contextOptions = testHelper.CreateOptions( + testHelper.CreateServiceProvider(new ServiceCollection().AddSingleton(migrationsAssembly))); + + var testContext = new TestDbContext(contextOptions); + + Assert.True(testContext.Database.HasPendingModelChanges()); + } + + [ConditionalFact] + public void HasPendingModelChanges_has_migrations_and_no_new_context_changes_returns_false() + { + var fakeModelSnapshot = new FakeModelSnapshot(builder => + { + // TODO: This seems fragile, what should I do? + builder.HasAnnotation("ProductVersion", "8.0.0-dev"); + + builder.Entity("Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensionsTests.TestDbContext.Simple", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("Simples"); + }); + }); + var migrationsAssembly = new FakeIMigrationsAssembly + { + ModelSnapshot = null, + Migrations = new Dictionary(), + }; + + var testHelper = FakeRelationalTestHelpers.Instance; + + var contextOptions = testHelper.CreateOptions( + testHelper.CreateServiceProvider(new ServiceCollection().AddSingleton(migrationsAssembly))); + + var testContext = new TestDbContext(contextOptions); + + Assert.True(testContext.Database.HasPendingModelChanges()); + } + + private class TestDbContext : DbContext + { + public TestDbContext(DbContextOptions options) : base(options) + { } + public DbSet Simples { get; set; } + + public class Simple + { + public int Id { get; set; } + } + + } + + private class FakeModelSnapshot : ModelSnapshot + { + private readonly Action _buildModel; + + public FakeModelSnapshot(Action buildModel) + { + _buildModel = buildModel; + } + protected override void BuildModel(ModelBuilder modelBuilder) + { + _buildModel(modelBuilder); + } + } + + private class FakeHistoryRepository : IHistoryRepository { public List AppliedMigrations { get; set; } From 5ac0582edbeafc1ccfa3348fa5eb2b0fccc60cc4 Mon Sep 17 00:00:00 2001 From: Brice Lambson Date: Tue, 18 Jul 2023 09:49:39 -0700 Subject: [PATCH 2/2] Clean up PR #31164 --- .../Design/Internal/MigrationsOperations.cs | 2 +- src/EFCore.Design/Design/OperationExecutor.cs | 12 ++++++------ .../Extensions/RelationalDatabaseFacadeExtensions.cs | 6 +++--- .../MigrationsHasPendingModelChangesCommand.cs | 2 +- src/ef/IOperationExecutor.cs | 2 +- src/ef/OperationExecutorBase.cs | 4 ++-- .../RelationalDatabaseFacadeExtensionsTest.cs | 10 +++------- 7 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/EFCore.Design/Design/Internal/MigrationsOperations.cs b/src/EFCore.Design/Design/Internal/MigrationsOperations.cs index 3f105e7ba87..e597ec6afd5 100644 --- a/src/EFCore.Design/Design/Internal/MigrationsOperations.cs +++ b/src/EFCore.Design/Design/Internal/MigrationsOperations.cs @@ -249,7 +249,7 @@ public virtual MigrationFiles RemoveMigration( /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// - public virtual void CheckPendingMigrations(string? contextType) + public virtual void HasPendingModelChanges(string? contextType) { using var context = _contextOperations.CreateContext(contextType); diff --git a/src/EFCore.Design/Design/OperationExecutor.cs b/src/EFCore.Design/Design/OperationExecutor.cs index 715ecfe5421..046be5f92a5 100644 --- a/src/EFCore.Design/Design/OperationExecutor.cs +++ b/src/EFCore.Design/Design/OperationExecutor.cs @@ -686,10 +686,10 @@ private string ScriptDbContextImpl(string? contextType) /// /// Represents an operation to check if there are any pending migrations. /// - public class CheckPendingMigrations : OperationBase + public class HasPendingModelChanges : OperationBase { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// The arguments supported by are: @@ -698,7 +698,7 @@ public class CheckPendingMigrations : OperationBase /// The operation executor. /// The . /// The operation arguments. - public CheckPendingMigrations( + public HasPendingModelChanges( OperationExecutor executor, IOperationResultHandler resultHandler, IDictionary args) @@ -709,12 +709,12 @@ public CheckPendingMigrations( var contextType = (string?)args["contextType"]; - Execute(() => executor.CheckPendingMigrationsImpl(contextType)); + Execute(() => executor.HasPendingModelChangesImpl(contextType)); } } - private void CheckPendingMigrationsImpl(string? contextType) - => MigrationsOperations.CheckPendingMigrations(contextType); + private void HasPendingModelChangesImpl(string? contextType) + => MigrationsOperations.HasPendingModelChanges(contextType); /// diff --git a/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs b/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs index 694d0f7e285..51d2701fbb6 100644 --- a/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs +++ b/src/EFCore.Relational/Extensions/RelationalDatabaseFacadeExtensions.cs @@ -955,10 +955,10 @@ public static bool IsRelational(this DatabaseFacade databaseFacade) /// /// Returns if the model has pending changes to be applied. /// - /// Tbe facade from . + /// The facade from . /// - /// if the database model has pending changes. - /// if a new migration has to be added. + /// if the database model has pending changes + /// and a new migration has to be added. /// public static bool HasPendingModelChanges(this DatabaseFacade databaseFacade) { diff --git a/src/ef/Commands/MigrationsHasPendingModelChangesCommand.cs b/src/ef/Commands/MigrationsHasPendingModelChangesCommand.cs index 57068b8e53e..bdbd2db8b6a 100644 --- a/src/ef/Commands/MigrationsHasPendingModelChangesCommand.cs +++ b/src/ef/Commands/MigrationsHasPendingModelChangesCommand.cs @@ -9,7 +9,7 @@ protected override int Execute(string[] args) { using var executor = CreateExecutor(args); - executor.CheckPendingMigrations(Context!.Value()); + executor.HasPendingModelChanges(Context!.Value()); return base.Execute(args); } diff --git a/src/ef/IOperationExecutor.cs b/src/ef/IOperationExecutor.cs index 432c2df68f5..e77caaab7c7 100644 --- a/src/ef/IOperationExecutor.cs +++ b/src/ef/IOperationExecutor.cs @@ -37,5 +37,5 @@ IDictionary ScaffoldContext( string ScriptMigration(string? fromMigration, string? toMigration, bool idempotent, bool noTransactions, string? contextType); string ScriptDbContext(string? contextType); - void CheckPendingMigrations(string? contextType); + void HasPendingModelChanges(string? contextType); } diff --git a/src/ef/OperationExecutorBase.cs b/src/ef/OperationExecutorBase.cs index a4fcd85546c..8e578bebc8f 100644 --- a/src/ef/OperationExecutorBase.cs +++ b/src/ef/OperationExecutorBase.cs @@ -207,8 +207,8 @@ public string ScriptDbContext(string? contextType) "ScriptDbContext", new Dictionary { ["contextType"] = contextType }); - public void CheckPendingMigrations(string? contextType) + public void HasPendingModelChanges(string? contextType) => InvokeOperation( - "CheckPendingMigrations", + "HasPendingModelChanges", new Dictionary { ["contextType"] = contextType }); } diff --git a/test/EFCore.Relational.Tests/RelationalDatabaseFacadeExtensionsTest.cs b/test/EFCore.Relational.Tests/RelationalDatabaseFacadeExtensionsTest.cs index dc0dcec8f1b..5f1a269d466 100644 --- a/test/EFCore.Relational.Tests/RelationalDatabaseFacadeExtensionsTest.cs +++ b/test/EFCore.Relational.Tests/RelationalDatabaseFacadeExtensionsTest.cs @@ -3,7 +3,6 @@ using System.Transactions; using Microsoft.EntityFrameworkCore.InMemory.Storage.Internal; -using Microsoft.EntityFrameworkCore.TestModels.UpdatesModel; using Microsoft.EntityFrameworkCore.TestUtilities.FakeProvider; using IsolationLevel = System.Data.IsolationLevel; @@ -275,14 +274,11 @@ public void HasPendingModelChanges_has_migrations_and_no_new_context_changes_ret { var fakeModelSnapshot = new FakeModelSnapshot(builder => { - // TODO: This seems fragile, what should I do? - builder.HasAnnotation("ProductVersion", "8.0.0-dev"); - builder.Entity("Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensionsTests.TestDbContext.Simple", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("int"); + .HasColumnType("default_int_mapping"); b.HasKey("Id"); @@ -291,7 +287,7 @@ public void HasPendingModelChanges_has_migrations_and_no_new_context_changes_ret }); var migrationsAssembly = new FakeIMigrationsAssembly { - ModelSnapshot = null, + ModelSnapshot = fakeModelSnapshot, Migrations = new Dictionary(), }; @@ -302,7 +298,7 @@ public void HasPendingModelChanges_has_migrations_and_no_new_context_changes_ret var testContext = new TestDbContext(contextOptions); - Assert.True(testContext.Database.HasPendingModelChanges()); + Assert.False(testContext.Database.HasPendingModelChanges()); } private class TestDbContext : DbContext