diff --git a/src/EFCore.Design/Design/Internal/DatabaseOperations.cs b/src/EFCore.Design/Design/Internal/DatabaseOperations.cs index 7ce91cb6448..77033f82a00 100644 --- a/src/EFCore.Design/Design/Internal/DatabaseOperations.cs +++ b/src/EFCore.Design/Design/Internal/DatabaseOperations.cs @@ -69,6 +69,8 @@ public virtual SavedModelFiles ScaffoldContext( [CanBeNull] string dbContextClassName, [NotNull] IEnumerable schemas, [NotNull] IEnumerable tables, + [CanBeNull] string modelNamespace, + [CanBeNull] string contextNamespace, bool useDataAnnotations, bool overwriteFiles, bool useDatabaseNames) @@ -90,8 +92,11 @@ public virtual SavedModelFiles ScaffoldContext( var scaffolder = services.GetRequiredService(); - var modelNamespace = GetNamespaceFromOutputPath(outputDir); - var contextNamespace = GetNamespaceFromOutputPath(outputContextDir); + var finalModelNamespace = modelNamespace ?? GetNamespaceFromOutputPath(outputDir); + var finalContextNamespace = + contextNamespace ?? + modelNamespace ?? + GetNamespaceFromOutputPath(outputContextDir); var scaffoldedModel = scaffolder.ScaffoldModel( connectionString, @@ -101,8 +106,8 @@ public virtual SavedModelFiles ScaffoldContext( { UseDataAnnotations = useDataAnnotations, RootNamespace = _rootNamespace, - ModelNamespace = modelNamespace, - ContextNamespace = contextNamespace, + ModelNamespace = finalModelNamespace, + ContextNamespace = finalContextNamespace, Language = _language, ContextDir = MakeDirRelative(outputDir, outputContextDir), ContextName = dbContextClassName diff --git a/src/EFCore.Design/Design/Internal/MigrationsOperations.cs b/src/EFCore.Design/Design/Internal/MigrationsOperations.cs index de286b89cd1..24364a798ff 100644 --- a/src/EFCore.Design/Design/Internal/MigrationsOperations.cs +++ b/src/EFCore.Design/Design/Internal/MigrationsOperations.cs @@ -78,7 +78,8 @@ public MigrationsOperations( public virtual MigrationFiles AddMigration( [NotNull] string name, [CanBeNull] string outputDir, - [CanBeNull] string contextType) + [CanBeNull] string contextType, + [CanBeNull] string @namespace) { Check.NotEmpty(name, nameof(name)); @@ -102,7 +103,10 @@ public virtual MigrationFiles AddMigration( EnsureMigrationsAssembly(services); var scaffolder = services.GetRequiredService(); - var migration = scaffolder.ScaffoldMigration(name, _rootNamespace, subNamespace, _language); + var migration = + string.IsNullOrEmpty(@namespace) + ? scaffolder.ScaffoldMigration(name, _rootNamespace, subNamespace, _language) + : scaffolder.ScaffoldMigration(name, null, @namespace, _language); var files = scaffolder.Save(_projectDir, migration, outputDir); return files; diff --git a/src/EFCore.Design/Design/OperationExecutor.cs b/src/EFCore.Design/Design/OperationExecutor.cs index 1ccda89c4c9..755223fda9f 100644 --- a/src/EFCore.Design/Design/OperationExecutor.cs +++ b/src/EFCore.Design/Design/OperationExecutor.cs @@ -160,22 +160,25 @@ public AddMigration( var name = (string)args["name"]; var outputDir = (string)args["outputDir"]; var contextType = (string)args["contextType"]; + var @namespace = (string)args["namespace"]; - Execute(() => executor.AddMigrationImpl(name, outputDir, contextType)); + Execute(() => executor.AddMigrationImpl(name, outputDir, contextType, @namespace)); } } private IDictionary AddMigrationImpl( [NotNull] string name, [CanBeNull] string outputDir, - [CanBeNull] string contextType) + [CanBeNull] string contextType, + [CanBeNull] string @namespace) { Check.NotEmpty(name, nameof(name)); var files = MigrationsOperations.AddMigration( name, outputDir, - contextType); + contextType, + @namespace); return new Hashtable { @@ -443,6 +446,8 @@ public class ScaffoldContext : OperationBase /// useDataAnnotations--Use attributes to configure the model (where possible). If false, only the fluent API is used. /// overwriteFiles--Overwrite existing files. /// useDatabaseNames--Use table and column names directly from the database. + /// modelNamespace--Specify to override the namespace of the generated entity types. + /// contextNamespace--Specify to override the namespace of the generated DbContext class. /// /// The operation executor. /// The . @@ -461,6 +466,8 @@ public ScaffoldContext( var dbContextClassName = (string)args["dbContextClassName"]; var schemaFilters = (IEnumerable)args["schemaFilters"]; var tableFilters = (IEnumerable)args["tableFilters"]; + var modelNamespace = (string)args["modelNamespace"]; + var contextNamespace = (string)args["contextNamespace"]; var useDataAnnotations = (bool)args["useDataAnnotations"]; var overwriteFiles = (bool)args["overwriteFiles"]; var useDatabaseNames = (bool)args["useDatabaseNames"]; @@ -468,7 +475,8 @@ public ScaffoldContext( Execute( () => executor.ScaffoldContextImpl( provider, connectionString, outputDir, outputDbContextDir, dbContextClassName, - schemaFilters, tableFilters, useDataAnnotations, overwriteFiles, useDatabaseNames)); + schemaFilters, tableFilters, modelNamespace, contextNamespace, useDataAnnotations, + overwriteFiles, useDatabaseNames)); } } @@ -480,6 +488,8 @@ private IDictionary ScaffoldContextImpl( [CanBeNull] string dbContextClassName, [NotNull] IEnumerable schemaFilters, [NotNull] IEnumerable tableFilters, + [CanBeNull] string modelNamespace, + [CanBeNull] string contextNamespace, bool useDataAnnotations, bool overwriteFiles, bool useDatabaseNames) @@ -491,7 +501,8 @@ private IDictionary ScaffoldContextImpl( var files = DatabaseOperations.ScaffoldContext( provider, connectionString, outputDir, outputDbContextDir, dbContextClassName, - schemaFilters, tableFilters, useDataAnnotations, overwriteFiles, useDatabaseNames); + schemaFilters, tableFilters, modelNamespace, contextNamespace, useDataAnnotations, + overwriteFiles, useDatabaseNames); return new Hashtable { ["ContextFile"] = files.ContextFile, ["EntityTypeFiles"] = files.AdditionalFiles.ToArray() }; } diff --git a/src/EFCore.Design/Migrations/Design/IMigrationsScaffolder.cs b/src/EFCore.Design/Migrations/Design/IMigrationsScaffolder.cs index 0644e6cdc7e..280df291cd0 100644 --- a/src/EFCore.Design/Migrations/Design/IMigrationsScaffolder.cs +++ b/src/EFCore.Design/Migrations/Design/IMigrationsScaffolder.cs @@ -20,7 +20,7 @@ public interface IMigrationsScaffolder /// The scaffolded migration. ScaffoldedMigration ScaffoldMigration( [NotNull] string migrationName, - [NotNull] string rootNamespace, + [CanBeNull] string rootNamespace, [CanBeNull] string subNamespace = null, [CanBeNull] string language = null); diff --git a/src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs b/src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs index fe762243212..0559b8803a4 100644 --- a/src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs +++ b/src/EFCore.Design/Migrations/Design/MigrationsScaffolder.cs @@ -53,7 +53,7 @@ public MigrationsScaffolder([NotNull] MigrationsScaffolderDependencies dependenc /// The scaffolded migration. public virtual ScaffoldedMigration ScaffoldMigration( [NotNull] string migrationName, - [NotNull] string rootNamespace, + [CanBeNull] string rootNamespace, [CanBeNull] string subNamespace) => ScaffoldMigration(migrationName, rootNamespace, subNamespace, language: null); @@ -61,8 +61,14 @@ public virtual ScaffoldedMigration ScaffoldMigration( /// Scaffolds a new migration. /// /// The migration's name. - /// The project's root namespace. - /// The migration's sub-namespace. + /// + /// The project's root namespace, null to indicate no automatic + /// namespace generation, just use sub-namespace as is. + /// + /// + /// The migration's sub-namespace. Note: the root-namespace and + /// the sub-namespace should not both be empty. + /// /// The project's language. /// The scaffolded migration. public virtual ScaffoldedMigration ScaffoldMigration( @@ -72,15 +78,15 @@ public virtual ScaffoldedMigration ScaffoldMigration( string language = null) { Check.NotEmpty(migrationName, nameof(migrationName)); - Check.NotEmpty(rootNamespace, nameof(rootNamespace)); if (Dependencies.MigrationsAssembly.FindMigrationId(migrationName) != null) { throw new OperationException(DesignStrings.DuplicateMigrationName(migrationName)); } + var overrideNamespace = rootNamespace == null; var subNamespaceDefaulted = false; - if (string.IsNullOrEmpty(subNamespace)) + if (string.IsNullOrEmpty(subNamespace) && !overrideNamespace) { subNamespaceDefaulted = true; subNamespace = "Migrations"; @@ -88,7 +94,14 @@ public virtual ScaffoldedMigration ScaffoldMigration( var lastMigration = Dependencies.MigrationsAssembly.Migrations.LastOrDefault(); - var migrationNamespace = rootNamespace + "." + subNamespace; + var migrationNamespace = + (!string.IsNullOrEmpty(rootNamespace) + && !string.IsNullOrEmpty(subNamespace)) + ? rootNamespace + "." + subNamespace + : !string.IsNullOrEmpty(rootNamespace) + ? rootNamespace + : subNamespace; + if (subNamespaceDefaulted) { migrationNamespace = GetNamespace(lastMigration.Value?.AsType(), migrationNamespace); @@ -105,9 +118,14 @@ public virtual ScaffoldedMigration ScaffoldMigration( { if (subNamespaceDefaulted) { - var builder = new StringBuilder() - .Append(rootNamespace) - .Append(".Migrations."); + var builder = new StringBuilder(); + if (!string.IsNullOrEmpty(rootNamespace)) + { + builder.Append(rootNamespace); + builder.Append("."); + } + + builder.Append("Migrations."); if (sanitizedContextName.EndsWith("Context", StringComparison.Ordinal)) { @@ -136,7 +154,9 @@ public virtual ScaffoldedMigration ScaffoldMigration( ? Dependencies.MigrationsModelDiffer.GetDifferences(Dependencies.Model.GetRelationalModel(), lastModel) : new List(); var migrationId = Dependencies.MigrationsIdGenerator.GenerateId(migrationName); - var modelSnapshotNamespace = GetNamespace(modelSnapshot?.GetType(), migrationNamespace); + var modelSnapshotNamespace = overrideNamespace + ? migrationNamespace + : GetNamespace(modelSnapshot?.GetType(), migrationNamespace); var modelSnapshotName = sanitizedContextName + "ModelSnapshot"; if (modelSnapshot != null) diff --git a/src/EFCore.Tools/tools/EntityFrameworkCore.PS2.psm1 b/src/EFCore.Tools/tools/EntityFrameworkCore.PS2.psm1 index 6de26ba2eed..7bea2c5b75e 100644 --- a/src/EFCore.Tools/tools/EntityFrameworkCore.PS2.psm1 +++ b/src/EFCore.Tools/tools/EntityFrameworkCore.PS2.psm1 @@ -25,6 +25,9 @@ $versionErrorMessage = 'The Entity Framework Core Package Manager Console Tools .PARAMETER StartupProject The startup project to use. Defaults to the solution's startup project. +.PARAMETER Namespace + Specify to override the namespace for the migration. + .LINK Remove-Migration Update-Database @@ -35,7 +38,8 @@ function Add-Migration( $OutputDir, $Context, $Project, - $StartupProject) + $StartupProject, + $Namespace) { WarnIfEF6 'Add-Migration' throw $UpdatePowerShell @@ -177,6 +181,12 @@ function Remove-Migration( .PARAMETER StartupProject The startup project to use. Defaults to the solution's startup project. +.PARAMETER Namespace + Specify to override the namespace for the generated entity types. + +.PARAMETER ContextNamespace + Specify to override the namespace for the DbContext class. + .LINK about_EntityFrameworkCore #> @@ -192,7 +202,9 @@ function Scaffold-DbContext( [switch] $UseDatabaseNames, [switch] $Force, $Project, - $StartupProject) + $StartupProject, + $Namespace, + $ContextNamespace) { throw $UpdatePowerShell } diff --git a/src/EFCore.Tools/tools/EntityFrameworkCore.psm1 b/src/EFCore.Tools/tools/EntityFrameworkCore.psm1 index 53d8c5fd7ad..fd44f78e08d 100644 --- a/src/EFCore.Tools/tools/EntityFrameworkCore.psm1 +++ b/src/EFCore.Tools/tools/EntityFrameworkCore.psm1 @@ -33,6 +33,9 @@ Register-TabExpansion Add-Migration @{ .PARAMETER StartupProject The startup project to use. Defaults to the solution's startup project. +.PARAMETER Namespace + Specify to override the namespace for the migration. + .LINK Remove-Migration Update-Database @@ -47,7 +50,8 @@ function Add-Migration [string] $OutputDir, [string] $Context, [string] $Project, - [string] $StartupProject) + [string] $StartupProject, + [string] $Namespace) WarnIfEF6 'Add-Migration' @@ -61,6 +65,11 @@ function Add-Migration $params += '--output-dir', $OutputDir } + if ($Namespace) + { + $params += '--namespace', $Namespace + } + $params += GetParams $Context # NB: -join is here to support ConvertFrom-Json on PowerShell 3.0 @@ -305,6 +314,12 @@ Register-TabExpansion Scaffold-DbContext @{ .PARAMETER StartupProject The startup project to use. Defaults to the solution's startup project. +.PARAMETER Namespace + Specify to override the namespace for the generated entity types. + +.PARAMETER ContextNamespace + Specify to override the namespace for the DbContext class. + .LINK about_EntityFrameworkCore #> @@ -325,7 +340,9 @@ function Scaffold-DbContext [switch] $UseDatabaseNames, [switch] $Force, [string] $Project, - [string] $StartupProject) + [string] $StartupProject, + [string] $Namespace, + [string] $ContextNamespace) $dteProject = GetProject $Project $dteStartupProject = GetStartupProject $StartupProject $dteProject @@ -347,6 +364,16 @@ function Scaffold-DbContext $params += '--context', $Context } + if ($Namespace) + { + $params += '--namespace', $Namespace + } + + if ($ContextNamespace) + { + $params += '--context-namespace', $ContextNamespace + } + $params += $Schemas | %{ '--schema', $_ } $params += $Tables | %{ '--table', $_ } diff --git a/src/dotnet-ef/Properties/Resources.Designer.cs b/src/dotnet-ef/Properties/Resources.Designer.cs index ea95e999de0..33798b580ff 100644 --- a/src/dotnet-ef/Properties/Resources.Designer.cs +++ b/src/dotnet-ef/Properties/Resources.Designer.cs @@ -452,6 +452,24 @@ public static string InvalidTemplatePattern([CanBeNull] object template) public static string DbContextConnectionDescription => GetString("DbContextConnectionDescription"); + /// + /// Specify to override the namespace for the generated entity types. + /// + public static string NamespaceDescription + => GetString("NamespaceDescription"); + + /// + /// Specify to override the namespace for the DbContext class. + /// + public static string ContextNamespaceDescription + => GetString("ContextNamespaceDescription"); + + /// + /// Specify to override the namespace for the migration. + /// + public static string MigrationsNamespaceDescription + => GetString("MigrationsNamespaceDescription"); + private static string GetString(string name, params string[] formatterNames) { var value = _resourceManager.GetString(name); diff --git a/src/dotnet-ef/Properties/Resources.resx b/src/dotnet-ef/Properties/Resources.resx index 488497ebf90..dca7be6ced3 100644 --- a/src/dotnet-ef/Properties/Resources.resx +++ b/src/dotnet-ef/Properties/Resources.resx @@ -321,4 +321,13 @@ The connection string to the database. Defaults to the one specified in AddDbContext or OnConfiguring. + + Specify to override the namespace for the generated entity types. + + + Specify to override the namespace for the DbContext class. + + + Specify to override the namespace for the migration. + \ No newline at end of file diff --git a/src/ef/Commands/DbContextScaffoldCommand.Configure.cs b/src/ef/Commands/DbContextScaffoldCommand.Configure.cs index 5d2b246f9c0..97562035ddb 100644 --- a/src/ef/Commands/DbContextScaffoldCommand.Configure.cs +++ b/src/ef/Commands/DbContextScaffoldCommand.Configure.cs @@ -19,6 +19,8 @@ internal partial class DbContextScaffoldCommand : ProjectCommandBase private CommandOption _tables; private CommandOption _useDatabaseNames; private CommandOption _json; + private CommandOption _namespace; + private CommandOption _contextNamespace; public override void Configure(CommandLineApplication command) { @@ -36,6 +38,8 @@ public override void Configure(CommandLineApplication command) _tables = command.Option("-t|--table ...", Resources.TablesDescription); _useDatabaseNames = command.Option("--use-database-names", Resources.UseDatabaseNamesDescription); _json = Json.ConfigureOption(command); + _namespace = command.Option("-n|--namespace ", Resources.NamespaceDescription); + _contextNamespace = command.Option("--context-namespace ", Resources.ContextNamespaceDescription); base.Configure(command); } diff --git a/src/ef/Commands/DbContextScaffoldCommand.cs b/src/ef/Commands/DbContextScaffoldCommand.cs index 1b6d0905ba3..5c6725b56bc 100644 --- a/src/ef/Commands/DbContextScaffoldCommand.cs +++ b/src/ef/Commands/DbContextScaffoldCommand.cs @@ -37,7 +37,9 @@ protected override int Execute() _tables.Values, _dataAnnotations.HasValue(), _force.HasValue(), - _useDatabaseNames.HasValue()); + _useDatabaseNames.HasValue(), + _namespace.Value(), + _contextNamespace.Value()); if (_json.HasValue()) { ReportJsonResults(result); diff --git a/src/ef/Commands/MigrationsAddCommand.Configure.cs b/src/ef/Commands/MigrationsAddCommand.Configure.cs index 5e3cb049566..d223a4b9d5b 100644 --- a/src/ef/Commands/MigrationsAddCommand.Configure.cs +++ b/src/ef/Commands/MigrationsAddCommand.Configure.cs @@ -11,6 +11,7 @@ internal partial class MigrationsAddCommand : ContextCommandBase private CommandArgument _name; private CommandOption _outputDir; private CommandOption _json; + private CommandOption _namespace; public override void Configure(CommandLineApplication command) { @@ -20,6 +21,7 @@ public override void Configure(CommandLineApplication command) _outputDir = command.Option("-o|--output-dir ", Resources.MigrationsOutputDirDescription); _json = Json.ConfigureOption(command); + _namespace = command.Option("-n|--namespace ", Resources.MigrationsNamespaceDescription); base.Configure(command); } diff --git a/src/ef/Commands/MigrationsAddCommand.cs b/src/ef/Commands/MigrationsAddCommand.cs index 37031581bd5..1ae2ed839eb 100644 --- a/src/ef/Commands/MigrationsAddCommand.cs +++ b/src/ef/Commands/MigrationsAddCommand.cs @@ -21,7 +21,8 @@ protected override void Validate() protected override int Execute() { - var files = CreateExecutor().AddMigration(_name.Value, _outputDir.Value(), Context.Value()); + var files = CreateExecutor().AddMigration( + _name.Value, _outputDir.Value(), Context.Value(), _namespace.Value()); if (_json.HasValue()) { diff --git a/src/ef/IOperationExecutor.cs b/src/ef/IOperationExecutor.cs index 348afdb70f0..73be7242ba2 100644 --- a/src/ef/IOperationExecutor.cs +++ b/src/ef/IOperationExecutor.cs @@ -9,7 +9,7 @@ namespace Microsoft.EntityFrameworkCore.Tools { internal interface IOperationExecutor : IDisposable { - IDictionary AddMigration(string name, string outputDir, string contextType); + IDictionary AddMigration(string name, string outputDir, string contextType, string migrationNamespace); IDictionary RemoveMigration(string contextType, bool force); IEnumerable GetMigrations(string contextType); void DropDatabase(string contextType); @@ -27,7 +27,9 @@ IDictionary ScaffoldContext( IEnumerable tableFilters, bool useDataAnnotations, bool overwriteFiles, - bool useDatabaseNames); + bool useDatabaseNames, + string entityNamespace, + string dbContextNamespace); string ScriptMigration(string fromMigration, string toMigration, bool idempotent, string contextType); diff --git a/src/ef/OperationExecutorBase.cs b/src/ef/OperationExecutorBase.cs index 745e3952910..51b58026bb9 100644 --- a/src/ef/OperationExecutorBase.cs +++ b/src/ef/OperationExecutorBase.cs @@ -82,10 +82,16 @@ private object InvokeOperationImpl(string operationName, IDictionary arguments) return resultHandler.Result; } - public IDictionary AddMigration(string name, string outputDir, string contextType) + public IDictionary AddMigration(string name, string outputDir, string contextType, string @namespace) => InvokeOperation( "AddMigration", - new Dictionary { ["name"] = name, ["outputDir"] = outputDir, ["contextType"] = contextType }); + new Dictionary + { + ["name"] = name, + ["outputDir"] = outputDir, + ["contextType"] = contextType, + ["namespace"] = @namespace + }); public IDictionary RemoveMigration(string contextType, bool force) => InvokeOperation( @@ -130,7 +136,9 @@ public IDictionary ScaffoldContext( IEnumerable tableFilters, bool useDataAnnotations, bool overwriteFiles, - bool useDatabaseNames) + bool useDatabaseNames, + string modelNamespace, + string contextNamespace) => InvokeOperation( "ScaffoldContext", new Dictionary @@ -144,7 +152,9 @@ public IDictionary ScaffoldContext( ["tableFilters"] = tableFilters, ["useDataAnnotations"] = useDataAnnotations, ["overwriteFiles"] = overwriteFiles, - ["useDatabaseNames"] = useDatabaseNames + ["useDatabaseNames"] = useDatabaseNames, + ["modelNamespace"] = modelNamespace, + ["contextNamespace"] = contextNamespace }); public string ScriptMigration( diff --git a/src/ef/Properties/Resources.Designer.cs b/src/ef/Properties/Resources.Designer.cs index d11dedb2ed6..c07a37eb9ca 100644 --- a/src/ef/Properties/Resources.Designer.cs +++ b/src/ef/Properties/Resources.Designer.cs @@ -496,6 +496,24 @@ public static string InvalidTemplatePattern([CanBeNull] object template) public static string DbContextConnectionDescription => GetString("DbContextConnectionDescription"); + /// + /// Specify to override the namespace for the generated entity types. + /// + public static string NamespaceDescription + => GetString("NamespaceDescription"); + + /// + /// Specify to override the namespace for the DbContext class. + /// + public static string ContextNamespaceDescription + => GetString("ContextNamespaceDescription"); + + /// + /// Specify to override the namespace for the migration. + /// + public static string MigrationsNamespaceDescription + => GetString("MigrationsNamespaceDescription"); + private static string GetString(string name, params string[] formatterNames) { var value = _resourceManager.GetString(name); diff --git a/src/ef/Properties/Resources.resx b/src/ef/Properties/Resources.resx index aa1f4da0f95..6e1fd490e85 100644 --- a/src/ef/Properties/Resources.resx +++ b/src/ef/Properties/Resources.resx @@ -333,4 +333,13 @@ The connection string to the database. Defaults to the one specified in AddDbContext or OnConfiguring. + + Specify to override the namespace for the generated entity types. + + + Specify to override the namespace for the DbContext class. + + + Specify to override the namespace for the migration. + \ 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 d154b351669..6f065f03f79 100644 --- a/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs +++ b/test/EFCore.Design.Tests/Migrations/Design/MigrationScaffolderTest.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -48,6 +49,20 @@ public void ScaffoldMigration_handles_generic_contexts() Assert.Equal("GenericContextModelSnapshot", migration.SnapshotName); } + [ConditionalFact] + public void ScaffoldMigration_can_override_namespace() + { + var scaffolder = CreateMigrationScaffolder(); + + var migration = scaffolder.ScaffoldMigration("EmptyMigration", null, "OverrideNamespace.OverrideSubNamespace"); + + Assert.Contains("namespace OverrideNamespace.OverrideSubNamespace", migration.MigrationCode); + Assert.Equal("OverrideNamespace.OverrideSubNamespace", migration.MigrationSubNamespace); + + Assert.Contains("namespace OverrideNamespace.OverrideSubNamespace", migration.SnapshotCode); + Assert.Equal("OverrideNamespace.OverrideSubNamespace", migration.SnapshotSubnamespace); + } + private IMigrationsScaffolder CreateMigrationScaffolder() where TContext : DbContext, new() {