diff --git a/samples/OracleProvider/src/OracleProvider/Properties/OracleStrings.Designer.cs b/samples/OracleProvider/src/OracleProvider/Properties/OracleStrings.Designer.cs index ef915ab6142..b6fcdd4d08b 100644 --- a/samples/OracleProvider/src/OracleProvider/Properties/OracleStrings.Designer.cs +++ b/samples/OracleProvider/src/OracleProvider/Properties/OracleStrings.Designer.cs @@ -6,7 +6,6 @@ using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.Logging; -using System.Diagnostics; namespace Microsoft.EntityFrameworkCore.Internal { diff --git a/samples/OracleProvider/src/OracleProvider/Properties/OracleStrings.resx b/samples/OracleProvider/src/OracleProvider/Properties/OracleStrings.resx index 30413dde942..3ab6ca42afa 100644 --- a/samples/OracleProvider/src/OracleProvider/Properties/OracleStrings.resx +++ b/samples/OracleProvider/src/OracleProvider/Properties/OracleStrings.resx @@ -179,7 +179,7 @@ Found table with name: {name}. Debug OracleEventId.TableFound string - + Found index with name: {indexName}, table: {tableName}, is unique: {isUnique}. Debug OracleEventId.IndexFound string string bool @@ -195,5 +195,8 @@ For foreign key {foreignKeyName} on table {tableName}, unable to find the column called {principalColumnName} on the foreign key's principal table, {principaltableName}. Skipping foreign key. Warning OracleEventId.ForeignKeyPrincipalColumnMissingWarning string string string string - + + + The specified table '{table}' is not valid. Specify tables using the format '[schema].[table]'. + \ No newline at end of file diff --git a/src/EFCore.Design/Design/Internal/MigrationsOperations.cs b/src/EFCore.Design/Design/Internal/MigrationsOperations.cs index a4cef3aa986..51413ce85d4 100644 --- a/src/EFCore.Design/Design/Internal/MigrationsOperations.cs +++ b/src/EFCore.Design/Design/Internal/MigrationsOperations.cs @@ -105,7 +105,11 @@ private string SubnamespaceFromOutputPath(string outputDir) var subPath = outputDir.Substring(_projectDir.Length); return !string.IsNullOrWhiteSpace(subPath) - ? string.Join(".", subPath.Split(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }, StringSplitOptions.RemoveEmptyEntries)) + ? string.Join( + ".", + subPath.Split( + new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }, + StringSplitOptions.RemoveEmptyEntries)) : null; } @@ -176,7 +180,7 @@ public virtual void UpdateDatabase( /// directly from your code. This API may change or be removed in future releases. /// public virtual MigrationFiles RemoveMigration( - [CanBeNull] string contextType, bool force) + [CanBeNull] string contextType, bool force, bool revert) { using (var context = _contextOperations.CreateContext(contextType)) { @@ -186,7 +190,7 @@ public virtual MigrationFiles RemoveMigration( var scaffolder = services.GetRequiredService(); - var files = scaffolder.RemoveMigration(_projectDir, _rootNamespace, force, _language); + var files = scaffolder.RemoveMigration(_projectDir, _rootNamespace, force, revert, _language); _reporter.WriteInformation(DesignStrings.Done); diff --git a/src/EFCore.Design/Design/OperationExecutor.cs b/src/EFCore.Design/Design/OperationExecutor.cs index 3daac644b4e..01917e3c8af 100644 --- a/src/EFCore.Design/Design/OperationExecutor.cs +++ b/src/EFCore.Design/Design/OperationExecutor.cs @@ -295,15 +295,16 @@ public RemoveMigration( var contextType = (string)args["contextType"]; var force = (bool)args["force"]; + var revert = (bool)args["revert"]; - Execute(() => executor.RemoveMigrationImpl(contextType, force)); + Execute(() => executor.RemoveMigrationImpl(contextType, force, revert)); } } - private IDictionary RemoveMigrationImpl([CanBeNull] string contextType, bool force) + private IDictionary RemoveMigrationImpl([CanBeNull] string contextType, bool force, bool revert) { var files = _migrationsOperations.Value - .RemoveMigration(contextType, force); + .RemoveMigration(contextType, force, revert); return new Hashtable { diff --git a/src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs b/src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs index a5a3435e366..32f475108e3 100644 --- a/src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs +++ b/src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs @@ -206,7 +206,7 @@ protected virtual string GetSubNamespace([NotNull] string rootNamespace, [NotNul /// Don't check to see if the migration has been applied to the database. /// The removed migration files. public virtual MigrationFiles RemoveMigration([NotNull] string projectDir, [NotNull] string rootNamespace, bool force) - => RemoveMigration(projectDir, rootNamespace, force, language: null); + => RemoveMigration(projectDir, rootNamespace, force, revert: false, language: null); /// /// Removes the previous migration. @@ -214,6 +214,7 @@ public virtual MigrationFiles RemoveMigration([NotNull] string projectDir, [NotN /// The project's root directory. /// The project's root namespace. /// Don't check to see if the migration has been applied to the database. + /// Revert if the migration has been applied to the database before removing. /// The project's language. /// The removed migration files. // TODO: DRY (file names) @@ -221,6 +222,7 @@ public virtual MigrationFiles RemoveMigration( [NotNull] string projectDir, [NotNull] string rootNamespace, bool force, + bool revert, [CanBeNull] string language) { Check.NotEmpty(projectDir, nameof(projectDir)); @@ -254,7 +256,18 @@ public virtual MigrationFiles RemoveMigration( else if (Dependencies.HistoryRepository.GetAppliedMigrations().Any( e => e.MigrationId.Equals(migration.GetId(), StringComparison.OrdinalIgnoreCase))) { - throw new OperationException(DesignStrings.RevertMigration(migration.GetId())); + if (revert) + { + Dependencies.OperationReporter.WriteInformation(DesignStrings.RevertingMigration(migration.GetId())); + Dependencies.Migrator.Migrate( + migrations.Count > 1 + ? migrations[migrations.Count - 2].GetId() + : Migration.InitialDatabase); + } + else + { + throw new OperationException(DesignStrings.RevertMigration(migration.GetId())); + } } var migrationFileName = migration.GetId() + codeGenerator.FileExtension; diff --git a/src/EFCore.Design/Migrations/Design/MigrationsScaffolderDependencies.cs b/src/EFCore.Design/Migrations/Design/MigrationsScaffolderDependencies.cs index 10e6fdddc88..86e93ce8cd1 100644 --- a/src/EFCore.Design/Migrations/Design/MigrationsScaffolderDependencies.cs +++ b/src/EFCore.Design/Migrations/Design/MigrationsScaffolderDependencies.cs @@ -58,6 +58,7 @@ public sealed class MigrationsScaffolderDependencies /// The operation reporter. /// The database provider. /// The snapshot model processor. + /// The migrator. public MigrationsScaffolderDependencies( [NotNull] ICurrentDbContext currentDbContext, [NotNull] IModel model, @@ -68,7 +69,8 @@ public MigrationsScaffolderDependencies( [NotNull] IHistoryRepository historyRepository, [NotNull] IOperationReporter operationReporter, [NotNull] IDatabaseProvider databaseProvider, - [NotNull] ISnapshotModelProcessor snapshotModelProcessor) + [NotNull] ISnapshotModelProcessor snapshotModelProcessor, + [NotNull] IMigrator migrator) { Check.NotNull(currentDbContext, nameof(currentDbContext)); Check.NotNull(model, nameof(model)); @@ -80,6 +82,7 @@ public MigrationsScaffolderDependencies( Check.NotNull(operationReporter, nameof(operationReporter)); Check.NotNull(databaseProvider, nameof(databaseProvider)); Check.NotNull(snapshotModelProcessor, nameof(snapshotModelProcessor)); + Check.NotNull(migrator, nameof(migrator)); CurrentDbContext = currentDbContext; Model = model; @@ -91,6 +94,7 @@ public MigrationsScaffolderDependencies( OperationReporter = operationReporter; DatabaseProvider = databaseProvider; SnapshotModelProcessor = snapshotModelProcessor; + Migrator = migrator; } /// @@ -150,6 +154,11 @@ public IMigrationsCodeGenerator MigrationCodeGenerator /// public ISnapshotModelProcessor SnapshotModelProcessor { get; } + /// + /// The migrator. + /// + public IMigrator Migrator { get; } + /// /// Clones this dependency parameter object with one service replaced. /// @@ -166,7 +175,8 @@ public MigrationsScaffolderDependencies With([NotNull] ICurrentDbContext current HistoryRepository, OperationReporter, DatabaseProvider, - SnapshotModelProcessor); + SnapshotModelProcessor, + Migrator); /// /// Clones this dependency parameter object with one service replaced. @@ -184,7 +194,8 @@ public MigrationsScaffolderDependencies With([NotNull] IModel model) HistoryRepository, OperationReporter, DatabaseProvider, - SnapshotModelProcessor); + SnapshotModelProcessor, + Migrator); /// /// Clones this dependency parameter object with one service replaced. @@ -202,7 +213,8 @@ public MigrationsScaffolderDependencies With([NotNull] IMigrationsAssembly migra HistoryRepository, OperationReporter, DatabaseProvider, - SnapshotModelProcessor); + SnapshotModelProcessor, + Migrator); /// /// Clones this dependency parameter object with one service replaced. @@ -220,7 +232,8 @@ public MigrationsScaffolderDependencies With([NotNull] IMigrationsModelDiffer mi HistoryRepository, OperationReporter, DatabaseProvider, - SnapshotModelProcessor); + SnapshotModelProcessor, + Migrator); /// /// Clones this dependency parameter object with one service replaced. @@ -238,7 +251,8 @@ public MigrationsScaffolderDependencies With([NotNull] IMigrationsIdGenerator mi HistoryRepository, OperationReporter, DatabaseProvider, - SnapshotModelProcessor); + SnapshotModelProcessor, + Migrator); /// /// Clones this dependency parameter object with one service replaced. @@ -269,7 +283,8 @@ public MigrationsScaffolderDependencies With([NotNull] MigrationsCodeGeneratorSe HistoryRepository, OperationReporter, DatabaseProvider, - SnapshotModelProcessor); + SnapshotModelProcessor, + Migrator); /// /// Clones this dependency parameter object with one service replaced. @@ -287,7 +302,8 @@ public MigrationsScaffolderDependencies With([NotNull] IHistoryRepository histor historyRepository, OperationReporter, DatabaseProvider, - SnapshotModelProcessor); + SnapshotModelProcessor, + Migrator); /// /// Clones this dependency parameter object with one service replaced. @@ -305,7 +321,8 @@ public MigrationsScaffolderDependencies With([NotNull] IOperationReporter operat HistoryRepository, operationReporter, DatabaseProvider, - SnapshotModelProcessor); + SnapshotModelProcessor, + Migrator); /// /// Clones this dependency parameter object with one service replaced. @@ -323,7 +340,8 @@ public MigrationsScaffolderDependencies With([NotNull] IDatabaseProvider databas HistoryRepository, OperationReporter, databaseProvider, - SnapshotModelProcessor); + SnapshotModelProcessor, + Migrator); /// /// Clones this dependency parameter object with one service replaced. @@ -341,6 +359,26 @@ public MigrationsScaffolderDependencies With([NotNull] ISnapshotModelProcessor s HistoryRepository, OperationReporter, DatabaseProvider, - snapshotModelProcessor); + snapshotModelProcessor, + Migrator); + + /// + /// Clones this dependency parameter object with one service replaced. + /// + /// A replacement for the current dependency of this type. + /// A new parameter object with the given service replaced. + public MigrationsScaffolderDependencies With([NotNull] IMigrator migrator) + => new MigrationsScaffolderDependencies( + CurrentDbContext, + Model, + MigrationsAssembly, + MigrationsModelDiffer, + MigrationsIdGenerator, + MigrationCodeGeneratorSelector, + HistoryRepository, + OperationReporter, + DatabaseProvider, + SnapshotModelProcessor, + migrator); } } diff --git a/src/EFCore.Design/Properties/DesignStrings.Designer.cs b/src/EFCore.Design/Properties/DesignStrings.Designer.cs index 9f5ff2f3e70..92d0f62860f 100644 --- a/src/EFCore.Design/Properties/DesignStrings.Designer.cs +++ b/src/EFCore.Design/Properties/DesignStrings.Designer.cs @@ -572,14 +572,6 @@ public static string InvokeBuildWebHostFailed([CanBeNull] object startupClass, [ GetString("InvokeBuildWebHostFailed", nameof(startupClass), nameof(error)), startupClass, error); - /// - /// More than one {service} service was found for language '{language}'. Remove one of the conflicting NuGet packages or design-time service registrations and try again. - /// - public static string MultipleLanguageServices([CanBeNull] object service, [CanBeNull] object language) - => string.Format( - GetString("MultipleLanguageServices", nameof(service), nameof(language)), - service, language); - /// /// The project language '{language}' isn't supported by the built-in {service} service. You can try looking for an additional NuGet package which supports this language; moving your DbContext type to a C# class library referenced by this project; or manually implementing and registering the design-time service for programming language. /// @@ -588,6 +580,14 @@ public static string NoLanguageService([CanBeNull] object language, [CanBeNull] GetString("NoLanguageService", nameof(language), nameof(service)), language, service); + /// + /// Reverting migration '{name}'. + /// + public static string RevertingMigration([CanBeNull] object name) + => string.Format( + GetString("RevertingMigration", nameof(name)), + name); + private static string GetString(string name, params string[] formatterNames) { var value = _resourceManager.GetString(name); diff --git a/src/EFCore.Design/Properties/DesignStrings.resx b/src/EFCore.Design/Properties/DesignStrings.resx index 4c1701224f4..487aa164c02 100644 --- a/src/EFCore.Design/Properties/DesignStrings.resx +++ b/src/EFCore.Design/Properties/DesignStrings.resx @@ -342,4 +342,7 @@ Change your target project to the migrations project by using the Package Manage The project language '{language}' isn't supported by the built-in {service} service. You can try looking for an additional NuGet package which supports this language; moving your DbContext type to a C# class library referenced by this project; or manually implementing and registering the design-time service for programming language. + + Reverting migration '{name}'. + \ No newline at end of file diff --git a/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs b/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs index d3241fcde5f..f3b50cd9088 100644 --- a/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs +++ b/src/EFCore.SqlServer/Properties/SqlServerStrings.Designer.cs @@ -67,7 +67,7 @@ public static string TransientExceptionDetected => GetString("TransientExceptionDetected"); /// - /// No type was specified for the decimal column '{property}' on entity type '{entityType}'. This will cause values to be silently truncated if they do not fit in the default precision and scale. Explicitly specify the SQL server column type that can accomadate all the values using 'ForHasColumnType()'. + /// No type was specified for the decimal column '{property}' on entity type '{entityType}'. This will cause values to be silently truncated if they do not fit in the default precision and scale. Explicitly specify the SQL server column type that can accommodate all the values using 'ForHasColumnType()'. /// public static readonly EventDefinition LogDefaultDecimalTypeColumn = new EventDefinition( diff --git a/src/EFCore.Tools/tools/EntityFrameworkCore.psm1 b/src/EFCore.Tools/tools/EntityFrameworkCore.psm1 index 2ad04f2b646..fdd46efbc2b 100644 --- a/src/EFCore.Tools/tools/EntityFrameworkCore.psm1 +++ b/src/EFCore.Tools/tools/EntityFrameworkCore.psm1 @@ -199,6 +199,9 @@ Register-TabExpansion Remove-Migration @{ .PARAMETER Force Don't check to see if the migration has been applied to the database. Always implied on UWP apps. +.PARAMETER Revert + Revert the migration if it has been applied to the database. + .PARAMETER Context The DbContext to use. @@ -215,7 +218,7 @@ Register-TabExpansion Remove-Migration @{ function Remove-Migration { [CmdletBinding(PositionalBinding = $false)] - param([switch] $Force, [string] $Context, [string] $Project, [string] $StartupProject) + param([switch] $Force, [switch] $Revert, [string] $Context, [string] $Project, [string] $StartupProject) $dteProject = GetProject $Project $dteStartupProject = GetStartupProject $StartupProject $dteProject @@ -227,6 +230,11 @@ function Remove-Migration $params += '--force' } + if ($Revert) + { + $params += '--revert' + } + $params += GetParams $Context # NB: -join is here to support ConvertFrom-Json on PowerShell 3.0 diff --git a/src/dotnet-ef/Properties/Resources.Designer.cs b/src/dotnet-ef/Properties/Resources.Designer.cs index 7f6192fc459..7281fce2d38 100644 --- a/src/dotnet-ef/Properties/Resources.Designer.cs +++ b/src/dotnet-ef/Properties/Resources.Designer.cs @@ -1,5 +1,6 @@ // +using System; using System.Reflection; using System.Resources; using JetBrains.Annotations; @@ -377,6 +378,12 @@ public static string WritingFile([CanBeNull] object file) public static string NoBuildDescription => GetString("NoBuildDescription"); + /// + /// Revert the migration if it has been applied to the database. + /// + public static string MigrationsRemoveRevertDescription + => GetString("MigrationsRemoveRevertDescription"); + private static string GetString(string name, params string[] formatterNames) { var value = _resourceManager.GetString(name); diff --git a/src/dotnet-ef/Properties/Resources.Designer.tt b/src/dotnet-ef/Properties/Resources.Designer.tt index 2f70174a831..bf185453a8a 100644 --- a/src/dotnet-ef/Properties/Resources.Designer.tt +++ b/src/dotnet-ef/Properties/Resources.Designer.tt @@ -1,5 +1,6 @@ <# Session["ResourceFile"] = "Resources.resx"; Session["AccessModifier"] = "internal"; + Session["NoDiagnostics"] = true; #> <#@ include file="..\..\..\tools\Resources.tt" #> \ No newline at end of file diff --git a/src/dotnet-ef/Properties/Resources.resx b/src/dotnet-ef/Properties/Resources.resx index aa53689df16..eb45766ffdb 100644 --- a/src/dotnet-ef/Properties/Resources.resx +++ b/src/dotnet-ef/Properties/Resources.resx @@ -291,4 +291,7 @@ Don't build the project. Only use this when the build is up-to-date. + + Revert the migration if it has been applied to the database. + \ No newline at end of file diff --git a/src/ef/Commands/MigrationsRemoveCommand.Configure.cs b/src/ef/Commands/MigrationsRemoveCommand.Configure.cs index 7c1ab8024e0..b66cddfdf9c 100644 --- a/src/ef/Commands/MigrationsRemoveCommand.Configure.cs +++ b/src/ef/Commands/MigrationsRemoveCommand.Configure.cs @@ -9,6 +9,7 @@ namespace Microsoft.EntityFrameworkCore.Tools.Commands internal partial class MigrationsRemoveCommand : ContextCommandBase { private CommandOption _force; + private CommandOption _revert; private CommandOption _json; public override void Configure(CommandLineApplication command) @@ -16,6 +17,7 @@ public override void Configure(CommandLineApplication command) command.Description = Resources.MigrationsRemoveDescription; _force = command.Option("-f|--force", Resources.MigrationsRemoveForceDescription); + _revert = command.Option("-r|--revert", Resources.MigrationsRemoveRevertDescription); _json = Json.ConfigureOption(command); base.Configure(command); diff --git a/src/ef/Commands/MigrationsRemoveCommand.cs b/src/ef/Commands/MigrationsRemoveCommand.cs index 01797f68807..b06ccf8a991 100644 --- a/src/ef/Commands/MigrationsRemoveCommand.cs +++ b/src/ef/Commands/MigrationsRemoveCommand.cs @@ -10,7 +10,7 @@ partial class MigrationsRemoveCommand { protected override int Execute() { - var result = CreateExecutor().RemoveMigration(Context.Value(), _force.HasValue()); + var result = CreateExecutor().RemoveMigration(Context.Value(), _force.HasValue(), _revert.HasValue()); if (_json.HasValue()) { ReportJsonResults(result); diff --git a/src/ef/IOperationExecutor.cs b/src/ef/IOperationExecutor.cs index 6a51007434e..65116b64f0c 100644 --- a/src/ef/IOperationExecutor.cs +++ b/src/ef/IOperationExecutor.cs @@ -10,7 +10,7 @@ namespace Microsoft.EntityFrameworkCore.Tools internal interface IOperationExecutor : IDisposable { IDictionary AddMigration(string name, string outputDir, string contextType); - IDictionary RemoveMigration(string contextType, bool force); + IDictionary RemoveMigration(string contextType, bool force, bool revert); IEnumerable GetMigrations(string contextType); void DropDatabase(string contextType); IDictionary GetContextInfo(string name); diff --git a/src/ef/OperationExecutorBase.cs b/src/ef/OperationExecutorBase.cs index 0bf79f3e153..bd90c90ba7d 100644 --- a/src/ef/OperationExecutorBase.cs +++ b/src/ef/OperationExecutorBase.cs @@ -96,13 +96,14 @@ public IDictionary AddMigration(string name, string outputDir, string contextTyp ["contextType"] = contextType }); - public IDictionary RemoveMigration(string contextType, bool force) + public IDictionary RemoveMigration(string contextType, bool force, bool revert) => InvokeOperation( "RemoveMigration", new Dictionary { ["contextType"] = contextType, - ["force"] = force + ["force"] = force, + ["revert"] = revert }); public IEnumerable GetMigrations(string contextType) diff --git a/src/ef/Properties/Resources.Designer.cs b/src/ef/Properties/Resources.Designer.cs index 578d7db1b17..d59aec5a4dd 100644 --- a/src/ef/Properties/Resources.Designer.cs +++ b/src/ef/Properties/Resources.Designer.cs @@ -1,5 +1,6 @@ // +using System; using System.Reflection; using System.Resources; using JetBrains.Annotations; @@ -435,6 +436,12 @@ public static string Options([CanBeNull] object options) public static string LanguageDescription => GetString("LanguageDescription"); + /// + /// Revert the migration if it has been applied to the database. + /// + public static string MigrationsRemoveRevertDescription + => GetString("MigrationsRemoveRevertDescription"); + private static string GetString(string name, params string[] formatterNames) { var value = _resourceManager.GetString(name); diff --git a/src/ef/Properties/Resources.Designer.tt b/src/ef/Properties/Resources.Designer.tt index 2f70174a831..bf185453a8a 100644 --- a/src/ef/Properties/Resources.Designer.tt +++ b/src/ef/Properties/Resources.Designer.tt @@ -1,5 +1,6 @@ <# Session["ResourceFile"] = "Resources.resx"; Session["AccessModifier"] = "internal"; + Session["NoDiagnostics"] = true; #> <#@ include file="..\..\..\tools\Resources.tt" #> \ No newline at end of file diff --git a/src/ef/Properties/Resources.resx b/src/ef/Properties/Resources.resx index f7cd524710d..f090dc8e240 100644 --- a/src/ef/Properties/Resources.resx +++ b/src/ef/Properties/Resources.resx @@ -307,6 +307,9 @@ Options: {options} - The language. Defaults to 'C#'. + The language. Defaults to 'C#'. + + + Revert the migration if it has been applied to the database. \ No newline at end of file diff --git a/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs b/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs index 3ada2871433..072f7dac5c3 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Design.Internal; +using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; @@ -20,7 +21,7 @@ // ReSharper disable InconsistentNaming namespace Microsoft.EntityFrameworkCore.Migrations.Design { - public class MigrationScaffolderTest + public class MigrationsScaffolderTest { [Fact] public void ScaffoldMigration_reuses_model_snapshot() @@ -50,6 +51,12 @@ private MigrationsScaffolder CreateMigrationScaffolder() var idGenerator = new MigrationsIdGenerator(); var code = new CSharpHelper(); var reporter = new TestOperationReporter(); + var migrationAssembly + = new MigrationsAssembly( + currentContext, + new DbContextOptions().WithExtension(new FakeRelationalOptionsExtension()), + idGenerator); + var historyRepository = new MockHistoryRepository(); var services = RelationalTestHelpers.Instance.CreateContextServices(); @@ -57,10 +64,7 @@ private MigrationsScaffolder CreateMigrationScaffolder() new MigrationsScaffolderDependencies( currentContext, new Model(), - new MigrationsAssembly( - currentContext, - new DbContextOptions().WithExtension(new FakeRelationalOptionsExtension()), - idGenerator), + migrationAssembly, new MigrationsModelDiffer( new TestRelationalTypeMapper(new RelationalTypeMapperDependencies()), new MigrationsAnnotationProvider(new MigrationsAnnotationProviderDependencies()), @@ -79,10 +83,21 @@ private MigrationsScaffolder CreateMigrationScaffolder() new CSharpMigrationOperationGeneratorDependencies(code)), new CSharpSnapshotGenerator(new CSharpSnapshotGeneratorDependencies(code)))) }), - new MockHistoryRepository(), + historyRepository, reporter, new MockProvider(), - new SnapshotModelProcessor(reporter))); + new SnapshotModelProcessor(reporter), + new Migrator( + migrationAssembly, + historyRepository, + services.GetRequiredService(), + services.GetRequiredService(), + services.GetRequiredService(), + services.GetRequiredService(), + services.GetRequiredService(), + services.GetRequiredService(), + services.GetRequiredService>(), + services.GetRequiredService()))); } // ReSharper disable once UnusedTypeParameter diff --git a/tools/Resources.tt b/tools/Resources.tt index bd6db090955..87084406fe6 100644 --- a/tools/Resources.tt +++ b/tools/Resources.tt @@ -19,8 +19,15 @@ using System; using System.Reflection; using System.Resources; using JetBrains.Annotations; +<# + if (!model.NoDiagnostics) + { +#> using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.Logging; +<# + } +#> namespace <#= model.Namespace #> { @@ -86,13 +93,13 @@ namespace <#= model.Namespace #> <#= List(resource.Parameters) #>); <# } - else - { + else + { #> public static string <#= resource.Name #> => GetString("<#= resource.Name #>"); <# - } + } } } #> @@ -122,6 +129,13 @@ namespace <#= model.Namespace #> var services = (IServiceProvider)Host; var dte = (DTE)services.GetService(typeof(DTE)); + if (!Session.TryGetValue("NoDiagnostics", out var noDiagnostics)) + { + noDiagnostics = false; + } + + result.NoDiagnostics = (bool)noDiagnostics; + var resourceFile = (string)Session["ResourceFile"]; if (!Path.IsPathRooted(resourceFile)) { @@ -134,7 +148,7 @@ namespace <#= model.Namespace #> var rootNamespace = (string)project.Properties.Item("RootNamespace").Value; var resourceDir = Path.GetDirectoryName(resourceFile); var projectDir = (string)project.Properties.Item("FullPath").Value; - var resourceNamespace = rootNamespace + resourceDir.Substring(projectDir.Length) + var resourceNamespace = rootNamespace + "." + resourceDir.Substring(projectDir.Length) .Replace(Path.DirectorySeparatorChar, '.'); result.Namespace = (string)resourceProjectItem.Properties.Item("CustomToolNamespace")?.Value; @@ -150,7 +164,7 @@ namespace <#= model.Namespace #> using (var reader = new ResXResourceReader(resourceFile)) { reader.UseResXDataNodes = true; - + result.Resources = Enumerable.ToList( from DictionaryEntry r in reader select new Resource((ResXDataNode)r.Value)); @@ -178,6 +192,7 @@ namespace <#= model.Namespace #> public string Class { get; set; } public string ResourceName { get; set; } public IEnumerable Resources { get; set; } + public bool NoDiagnostics { get; set; } } class Resource