From 0c8d2563b075490f5876652305d48608ecf1a04c Mon Sep 17 00:00:00 2001 From: lajones Date: Wed, 6 May 2020 11:04:24 -0700 Subject: [PATCH 1/5] Fix for 19608. Truncate/Uniquify Sequence Names. (#20834) Fix for 19608. Truncate/Uniquify Sequence Names. --- .../RelationalConventionSetBuilder.cs | 1 + .../SequenceUniquificationConvention.cs | 61 +++++++++++++ .../Metadata/Internal/Sequence.cs | 37 +++++++- .../SequenceUniquificationConventionTest.cs | 85 +++++++++++++++++++ 4 files changed, 180 insertions(+), 4 deletions(-) create mode 100644 src/EFCore.Relational/Metadata/Conventions/SequenceUniquificationConvention.cs create mode 100644 test/EFCore.Relational.Tests/Metadata/Conventions/SequenceUniquificationConventionTest.cs diff --git a/src/EFCore.Relational/Metadata/Conventions/Infrastructure/RelationalConventionSetBuilder.cs b/src/EFCore.Relational/Metadata/Conventions/Infrastructure/RelationalConventionSetBuilder.cs index d1ed7791b15..8c4905ccf1e 100644 --- a/src/EFCore.Relational/Metadata/Conventions/Infrastructure/RelationalConventionSetBuilder.cs +++ b/src/EFCore.Relational/Metadata/Conventions/Infrastructure/RelationalConventionSetBuilder.cs @@ -106,6 +106,7 @@ public override ConventionSet CreateConventionSet() conventionSet.ModelFinalizingConventions.Add(dbFunctionAttributeConvention); conventionSet.ModelFinalizingConventions.Add(tableNameFromDbSetConvention); conventionSet.ModelFinalizingConventions.Add(storeGenerationConvention); + conventionSet.ModelFinalizingConventions.Add(new SequenceUniquificationConvention(Dependencies, RelationalDependencies)); conventionSet.ModelFinalizingConventions.Add(new SharedTableConvention(Dependencies, RelationalDependencies)); conventionSet.ModelFinalizingConventions.Add(new DbFunctionTypeMappingConvention(Dependencies, RelationalDependencies)); ReplaceConvention( diff --git a/src/EFCore.Relational/Metadata/Conventions/SequenceUniquificationConvention.cs b/src/EFCore.Relational/Metadata/Conventions/SequenceUniquificationConvention.cs new file mode 100644 index 00000000000..a2dfbd000d0 --- /dev/null +++ b/src/EFCore.Relational/Metadata/Conventions/SequenceUniquificationConvention.cs @@ -0,0 +1,61 @@ +// 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.Collections.Generic; +using System.Linq; +using JetBrains.Annotations; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata.Internal; + +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions +{ + /// + /// A convention which ensures that all sequences in the model have unique names + /// within a schema when truncated to the maximum identifier length for the model. + /// + public class SequenceUniquificationConvention : IModelFinalizingConvention + { + /// + /// Creates a new instance of . + /// + /// Parameter object containing dependencies for this convention. + /// Parameter object containing relational dependencies for this convention. + public SequenceUniquificationConvention( + [NotNull] ProviderConventionSetBuilderDependencies dependencies, + [NotNull] RelationalConventionSetBuilderDependencies relationalDependencies) + { + Dependencies = dependencies; + } + + /// + /// Parameter object containing service dependencies. + /// + protected virtual ProviderConventionSetBuilderDependencies Dependencies { get; } + + /// + public virtual void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext context) + { + var model = modelBuilder.Metadata; + var modelSequences = + (SortedDictionary<(string Name, string Schema), Sequence>)model[RelationalAnnotationNames.Sequences]; + + if (modelSequences != null) + { + var maxLength = model.GetMaxIdentifierLength(); + var toReplace = modelSequences + .Where(s => s.Key.Name.Length > maxLength).ToList(); + + foreach (var sequence in toReplace) + { + var schemaName = sequence.Key.Schema; + var newSequenceName = Uniquifier.Uniquify( + sequence.Key.Name, modelSequences, + sequenceName => (sequenceName, schemaName), maxLength); + Sequence.SetName((IMutableModel)model, sequence.Value, newSequenceName); + } + } + } + } +} diff --git a/src/EFCore.Relational/Metadata/Internal/Sequence.cs b/src/EFCore.Relational/Metadata/Internal/Sequence.cs index e4b336119f3..24f746b6137 100644 --- a/src/EFCore.Relational/Metadata/Internal/Sequence.cs +++ b/src/EFCore.Relational/Metadata/Internal/Sequence.cs @@ -24,7 +24,6 @@ public class Sequence : ConventionAnnotatable, IMutableSequence, IConventionSequ { private readonly IModel _model; - private readonly string _name; private readonly string _schema; private long? _startValue; private int? _incrementBy; @@ -105,7 +104,7 @@ public Sequence( Check.NullButNotEmpty(schema, nameof(schema)); _model = model; - _name = name; + Name = name; _schema = schema; _configurationSource = configurationSource; Builder = new InternalSequenceBuilder(this, ((IConventionModel)model).Builder); @@ -127,7 +126,7 @@ public Sequence([NotNull] IModel model, [NotNull] string annotationName) _configurationSource = ConfigurationSource.Explicit; var data = SequenceData.Deserialize((string)model[annotationName]); - _name = data.Name; + Name = data.Name; _schema = data.Schema; _startValue = data.StartValue; _incrementBy = data.IncrementBy; @@ -187,6 +186,36 @@ public static Sequence AddSequence( return sequence; } + /// + /// 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 static Sequence SetName( + [NotNull] IMutableModel model, [NotNull] Sequence sequence, [NotNull] string name) + { + Check.NotNull(model, nameof(model)); + Check.NotNull(sequence, nameof(sequence)); + Check.NotEmpty(name, nameof(name)); + + var sequences = (SortedDictionary<(string, string), Sequence>)model[RelationalAnnotationNames.Sequences]; + var tuple = (sequence.Name, sequence.Schema); + if (sequences == null + || !sequences.ContainsKey(tuple)) + { + return null; + } + + sequences.Remove(tuple); + + sequence.Name = name; + + sequences.Add((name, sequence.Schema), sequence); + + return sequence; + } + /// /// 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 @@ -230,7 +259,7 @@ public static Sequence RemoveSequence([NotNull] IMutableModel model, [NotNull] s /// 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 string Name => _name; + public virtual string Name { get; [param: NotNull] set; } /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to diff --git a/test/EFCore.Relational.Tests/Metadata/Conventions/SequenceUniquificationConventionTest.cs b/test/EFCore.Relational.Tests/Metadata/Conventions/SequenceUniquificationConventionTest.cs new file mode 100644 index 00000000000..9cc85ee33e5 --- /dev/null +++ b/test/EFCore.Relational.Tests/Metadata/Conventions/SequenceUniquificationConventionTest.cs @@ -0,0 +1,85 @@ +// 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 Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Internal; +using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; +using Microsoft.EntityFrameworkCore.TestUtilities; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +// ReSharper disable InconsistentNaming +namespace Microsoft.EntityFrameworkCore.Metadata.Conventions +{ + public class SequenceUniquificationConventionTest + { + [ConditionalFact] + public virtual void Sequence_names_are_truncated_and_uniquified() + { + var modelBuilder = GetModelBuilder(); + modelBuilder.GetInfrastructure().HasMaxIdentifierLength(10); + modelBuilder.HasSequence("UniquifyMeToo", (string)null); + modelBuilder.HasSequence("UniquifyMeToo", "TestSchema"); + modelBuilder.HasSequence("UniquifyM!Too", (string)null); + modelBuilder.HasSequence("UniquifyM!Too", "TestSchema"); + // the below ensure we deal with clashes with existing + // sequence names that look like candidate uniquified names + modelBuilder.HasSequence("UniquifyM~", (string)null); + modelBuilder.HasSequence("UniquifyM~", "TestSchema"); + + var model = modelBuilder.Model; + model.FinalizeModel(); + + Assert.Collection(model.GetSequences(), + s0 => + { + Assert.Equal("Uniquify~1", s0.Name); + Assert.Null(s0.Schema); + }, + s1 => + { + Assert.Equal("Uniquify~1", s1.Name); + Assert.Equal("TestSchema", s1.Schema); + }, + s2 => + { + Assert.Equal("Uniquify~2", s2.Name); + Assert.Null(s2.Schema); + }, + s3 => + { + Assert.Equal("Uniquify~2", s3.Name); + Assert.Equal("TestSchema", s3.Schema); + }, + s4 => + { + Assert.Equal("UniquifyM~", s4.Name); + Assert.Null(s4.Schema); + }, + s5 => + { + Assert.Equal("UniquifyM~", s5.Name); + Assert.Equal("TestSchema", s5.Schema); + }); + } + + private ModelBuilder GetModelBuilder() + { + var conventionSet = new ConventionSet(); + + var dependencies = CreateDependencies() + .With(new CurrentDbContext(new DbContext(new DbContextOptions()))); + var relationalDependencies = CreateRelationalDependencies(); + conventionSet.ModelFinalizingConventions.Add( + new SequenceUniquificationConvention(dependencies, relationalDependencies)); + + return new ModelBuilder(conventionSet); + } + + private ProviderConventionSetBuilderDependencies CreateDependencies() + => RelationalTestHelpers.Instance.CreateContextServices().GetRequiredService(); + + private RelationalConventionSetBuilderDependencies CreateRelationalDependencies() + => RelationalTestHelpers.Instance.CreateContextServices().GetRequiredService(); + } +} From 5b0b1b47634a6f6936a769e5412d06bc3b5271f3 Mon Sep 17 00:00:00 2001 From: lajones Date: Thu, 30 Apr 2020 13:29:18 -0700 Subject: [PATCH 2/5] Fix for 20526 and 19899. Allow suppression of OnConfiguring() generation. --- .../Design/Internal/DatabaseOperations.cs | 6 ++- src/EFCore.Design/Design/OperationExecutor.cs | 8 ++-- .../Internal/CSharpDbContextGenerator.cs | 14 +++++-- .../Internal/CSharpModelGenerator.cs | 3 +- .../Internal/ICSharpDbContextGenerator.cs | 3 +- .../Scaffolding/ModelCodeGenerationOptions.cs | 6 +++ .../tools/EntityFrameworkCore.PS2.psm1 | 4 ++ .../tools/EntityFrameworkCore.psm1 | 9 ++++ .../Properties/Resources.Designer.cs | 6 +++ src/dotnet-ef/Properties/Resources.resx | 3 ++ .../DbContextScaffoldCommand.Configure.cs | 2 + src/ef/Commands/DbContextScaffoldCommand.cs | 8 +++- src/ef/IOperationExecutor.cs | 3 +- src/ef/OperationExecutorBase.cs | 6 ++- src/ef/Properties/Resources.Designer.cs | 12 ++++++ src/ef/Properties/Resources.resx | 6 +++ .../Internal/CSharpDbContextGeneratorTest.cs | 42 +++++++++++++++++++ .../Internal/ModelCodeGeneratorTestBase.cs | 16 ++++++- 18 files changed, 140 insertions(+), 17 deletions(-) diff --git a/src/EFCore.Design/Design/Internal/DatabaseOperations.cs b/src/EFCore.Design/Design/Internal/DatabaseOperations.cs index e4ddbc368e8..c076491d9d6 100644 --- a/src/EFCore.Design/Design/Internal/DatabaseOperations.cs +++ b/src/EFCore.Design/Design/Internal/DatabaseOperations.cs @@ -76,7 +76,8 @@ public virtual SavedModelFiles ScaffoldContext( [CanBeNull] string contextNamespace, bool useDataAnnotations, bool overwriteFiles, - bool useDatabaseNames) + bool useDatabaseNames, + bool suppressOnConfiguring) { Check.NotEmpty(provider, nameof(provider)); Check.NotEmpty(connectionString, nameof(connectionString)); @@ -113,7 +114,8 @@ public virtual SavedModelFiles ScaffoldContext( ContextNamespace = finalContextNamespace, Language = _language, ContextDir = MakeDirRelative(outputDir, outputContextDir), - ContextName = dbContextClassName + ContextName = dbContextClassName, + SuppressOnConfiguring = suppressOnConfiguring }); return scaffolder.Save( diff --git a/src/EFCore.Design/Design/OperationExecutor.cs b/src/EFCore.Design/Design/OperationExecutor.cs index 2227eb31fca..c7b496803d7 100644 --- a/src/EFCore.Design/Design/OperationExecutor.cs +++ b/src/EFCore.Design/Design/OperationExecutor.cs @@ -471,12 +471,13 @@ public ScaffoldContext( var useDataAnnotations = (bool)args["useDataAnnotations"]; var overwriteFiles = (bool)args["overwriteFiles"]; var useDatabaseNames = (bool)args["useDatabaseNames"]; + var suppressOnConfiguring = (bool)args["suppressOnConfiguring"]; Execute( () => executor.ScaffoldContextImpl( provider, connectionString, outputDir, outputDbContextDir, dbContextClassName, schemaFilters, tableFilters, modelNamespace, contextNamespace, useDataAnnotations, - overwriteFiles, useDatabaseNames)); + overwriteFiles, useDatabaseNames, suppressOnConfiguring)); } } @@ -492,7 +493,8 @@ private IDictionary ScaffoldContextImpl( [CanBeNull] string contextNamespace, bool useDataAnnotations, bool overwriteFiles, - bool useDatabaseNames) + bool useDatabaseNames, + bool suppressOnConfiguring) { Check.NotNull(provider, nameof(provider)); Check.NotNull(connectionString, nameof(connectionString)); @@ -502,7 +504,7 @@ private IDictionary ScaffoldContextImpl( var files = DatabaseOperations.ScaffoldContext( provider, connectionString, outputDir, outputDbContextDir, dbContextClassName, schemaFilters, tableFilters, modelNamespace, contextNamespace, useDataAnnotations, - overwriteFiles, useDatabaseNames); + overwriteFiles, useDatabaseNames, suppressOnConfiguring); return new Hashtable { ["ContextFile"] = files.ContextFile, ["EntityTypeFiles"] = files.AdditionalFiles.ToArray() }; } diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.cs index 6de287bb1c1..6f947b6d06b 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CSharpDbContextGenerator.cs @@ -68,7 +68,8 @@ public virtual string WriteCode( string? contextNamespace, string modelNamespace, bool useDataAnnotations, - bool suppressConnectionStringWarning) + bool suppressConnectionStringWarning, + bool suppressOnConfiguring) { Check.NotNull(model, nameof(model)); @@ -97,7 +98,8 @@ public virtual string WriteCode( contextName, connectionString, useDataAnnotations, - suppressConnectionStringWarning); + suppressConnectionStringWarning, + suppressOnConfiguring); } _sb.AppendLine("}"); @@ -116,7 +118,8 @@ protected virtual void GenerateClass( [NotNull] string contextName, [NotNull] string connectionString, bool useDataAnnotations, - bool suppressConnectionStringWarning) + bool suppressConnectionStringWarning, + bool suppressOnConfiguring) { Check.NotNull(model, nameof(model)); Check.NotNull(contextName, nameof(contextName)); @@ -130,7 +133,10 @@ protected virtual void GenerateClass( GenerateConstructors(contextName); GenerateDbSets(model); GenerateEntityTypeErrors(model); - GenerateOnConfiguring(connectionString, suppressConnectionStringWarning); + if (!suppressOnConfiguring) + { + GenerateOnConfiguring(connectionString, suppressConnectionStringWarning); + } GenerateOnModelCreating(model, useDataAnnotations); } diff --git a/src/EFCore.Design/Scaffolding/Internal/CSharpModelGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/CSharpModelGenerator.cs index 6e6385bb434..d1e253a3fca 100644 --- a/src/EFCore.Design/Scaffolding/Internal/CSharpModelGenerator.cs +++ b/src/EFCore.Design/Scaffolding/Internal/CSharpModelGenerator.cs @@ -100,7 +100,8 @@ public override ScaffoldedModel GenerateModel( options.ContextNamespace, options.ModelNamespace, options.UseDataAnnotations, - options.SuppressConnectionStringWarning); + options.SuppressConnectionStringWarning, + options.SuppressOnConfiguring); // output DbContext .cs file var dbContextFileName = options.ContextName + FileExtension; diff --git a/src/EFCore.Design/Scaffolding/Internal/ICSharpDbContextGenerator.cs b/src/EFCore.Design/Scaffolding/Internal/ICSharpDbContextGenerator.cs index 5504b5feabf..07c07a62e6c 100644 --- a/src/EFCore.Design/Scaffolding/Internal/ICSharpDbContextGenerator.cs +++ b/src/EFCore.Design/Scaffolding/Internal/ICSharpDbContextGenerator.cs @@ -29,6 +29,7 @@ string WriteCode( [CanBeNull] string? contextNamespace, [NotNull] string modelNamespace, bool useDataAnnotations, - bool suppressConnectionStringWarning); + bool suppressConnectionStringWarning, + bool suppressOnConfiguring); } } diff --git a/src/EFCore.Design/Scaffolding/ModelCodeGenerationOptions.cs b/src/EFCore.Design/Scaffolding/ModelCodeGenerationOptions.cs index 0b2320efc05..a5ffabfa16b 100644 --- a/src/EFCore.Design/Scaffolding/ModelCodeGenerationOptions.cs +++ b/src/EFCore.Design/Scaffolding/ModelCodeGenerationOptions.cs @@ -24,6 +24,12 @@ public class ModelCodeGenerationOptions /// A value indicating whether to suppress the connection string sensitive information warning. public virtual bool SuppressConnectionStringWarning { get; set; } + /// + /// Gets or sets a value indicating whether to suppress generation of the OnConfiguring() method. + /// + /// A value indicating whether to suppress generation of the OnConfiguring() method. + public virtual bool SuppressOnConfiguring { get; set; } + /// /// Gets or sets the namespace of the project. /// diff --git a/src/EFCore.Tools/tools/EntityFrameworkCore.PS2.psm1 b/src/EFCore.Tools/tools/EntityFrameworkCore.PS2.psm1 index 7bea2c5b75e..bebc4763db7 100644 --- a/src/EFCore.Tools/tools/EntityFrameworkCore.PS2.psm1 +++ b/src/EFCore.Tools/tools/EntityFrameworkCore.PS2.psm1 @@ -175,6 +175,9 @@ function Remove-Migration( .PARAMETER Force Overwrite existing files. +.PARAMETER SuppressOnConfiguring + Suppress generation of the DbContext.OnConfiguring() method. + .PARAMETER Project The project to use. @@ -201,6 +204,7 @@ function Scaffold-DbContext( [switch] $DataAnnotations, [switch] $UseDatabaseNames, [switch] $Force, + [switch] $SuppressOnConfiguring, $Project, $StartupProject, $Namespace, diff --git a/src/EFCore.Tools/tools/EntityFrameworkCore.psm1 b/src/EFCore.Tools/tools/EntityFrameworkCore.psm1 index a9f1d3c3eb2..97ed4894ec1 100644 --- a/src/EFCore.Tools/tools/EntityFrameworkCore.psm1 +++ b/src/EFCore.Tools/tools/EntityFrameworkCore.psm1 @@ -359,6 +359,9 @@ Register-TabExpansion Scaffold-DbContext @{ .PARAMETER Force Overwrite existing files. +.PARAMETER SuppressOnConfiguring + Suppress generation of the DbContext.OnConfiguring() method. + .PARAMETER Project The project to use. @@ -393,6 +396,7 @@ function Scaffold-DbContext [switch] $DataAnnotations, [switch] $UseDatabaseNames, [switch] $Force, + [switch] $SuppressOnConfiguring, [string] $Project, [string] $StartupProject, [string] $Namespace, @@ -448,6 +452,11 @@ function Scaffold-DbContext $params += '--force' } + if ($SuppressOnConfiguring) + { + $params += '--no-on-configuring' + } + if ($RemainingArguments -ne $null) { $params += $RemainingArguments diff --git a/src/dotnet-ef/Properties/Resources.Designer.cs b/src/dotnet-ef/Properties/Resources.Designer.cs index 33798b580ff..14f40068f8f 100644 --- a/src/dotnet-ef/Properties/Resources.Designer.cs +++ b/src/dotnet-ef/Properties/Resources.Designer.cs @@ -470,6 +470,12 @@ public static string ContextNamespaceDescription public static string MigrationsNamespaceDescription => GetString("MigrationsNamespaceDescription"); + /// + /// Suppress generation of the DbContext.OnConfiguring() method. + /// + public static string SuppressOnConfiguringDescription + => GetString("SuppressOnConfiguringDescription"); + 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 dca7be6ced3..77f83f97764 100644 --- a/src/dotnet-ef/Properties/Resources.resx +++ b/src/dotnet-ef/Properties/Resources.resx @@ -330,4 +330,7 @@ Specify to override the namespace for the migration. + + Suppress generation of the DbContext.OnConfiguring() method. + \ No newline at end of file diff --git a/src/ef/Commands/DbContextScaffoldCommand.Configure.cs b/src/ef/Commands/DbContextScaffoldCommand.Configure.cs index 97562035ddb..72b98406778 100644 --- a/src/ef/Commands/DbContextScaffoldCommand.Configure.cs +++ b/src/ef/Commands/DbContextScaffoldCommand.Configure.cs @@ -21,6 +21,7 @@ internal partial class DbContextScaffoldCommand : ProjectCommandBase private CommandOption _json; private CommandOption _namespace; private CommandOption _contextNamespace; + private CommandOption _suppressOnConfiguring; public override void Configure(CommandLineApplication command) { @@ -40,6 +41,7 @@ public override void Configure(CommandLineApplication command) _json = Json.ConfigureOption(command); _namespace = command.Option("-n|--namespace ", Resources.NamespaceDescription); _contextNamespace = command.Option("--context-namespace ", Resources.ContextNamespaceDescription); + _suppressOnConfiguring = command.Option("--no-on-configuring", Resources.SuppressOnConfiguringDescription); base.Configure(command); } diff --git a/src/ef/Commands/DbContextScaffoldCommand.cs b/src/ef/Commands/DbContextScaffoldCommand.cs index 565ae5bf578..085bc8e8dd3 100644 --- a/src/ef/Commands/DbContextScaffoldCommand.cs +++ b/src/ef/Commands/DbContextScaffoldCommand.cs @@ -23,6 +23,11 @@ protected override void Validate() { throw new CommandException(Resources.MissingArgument(_provider.Name)); } + + if (!_suppressOnConfiguring.HasValue()) + { + Reporter.WriteWarning(Resources.OnConfiguringWarning); + } } protected override int Execute(string[] args) @@ -39,7 +44,8 @@ protected override int Execute(string[] args) _force.HasValue(), _useDatabaseNames.HasValue(), _namespace.Value(), - _contextNamespace.Value()); + _contextNamespace.Value(), + _suppressOnConfiguring.HasValue()); if (_json.HasValue()) { ReportJsonResults(result); diff --git a/src/ef/IOperationExecutor.cs b/src/ef/IOperationExecutor.cs index 55983184ab1..284a9a282d1 100644 --- a/src/ef/IOperationExecutor.cs +++ b/src/ef/IOperationExecutor.cs @@ -29,7 +29,8 @@ IDictionary ScaffoldContext( bool overwriteFiles, bool useDatabaseNames, string entityNamespace, - string dbContextNamespace); + string dbContextNamespace, + bool suppressOnConfiguring); string ScriptMigration(string fromMigration, string toMigration, bool idempotent, string contextType); diff --git a/src/ef/OperationExecutorBase.cs b/src/ef/OperationExecutorBase.cs index 876a3ce6af6..6f12a86af94 100644 --- a/src/ef/OperationExecutorBase.cs +++ b/src/ef/OperationExecutorBase.cs @@ -143,7 +143,8 @@ public IDictionary ScaffoldContext( bool overwriteFiles, bool useDatabaseNames, string modelNamespace, - string contextNamespace) + string contextNamespace, + bool suppressOnConfiguring) => InvokeOperation( "ScaffoldContext", new Dictionary @@ -159,7 +160,8 @@ public IDictionary ScaffoldContext( ["overwriteFiles"] = overwriteFiles, ["useDatabaseNames"] = useDatabaseNames, ["modelNamespace"] = modelNamespace, - ["contextNamespace"] = contextNamespace + ["contextNamespace"] = contextNamespace, + ["suppressOnConfiguring"] = suppressOnConfiguring }); public string ScriptMigration( diff --git a/src/ef/Properties/Resources.Designer.cs b/src/ef/Properties/Resources.Designer.cs index 05fb7b14dbf..070c4bc70e8 100644 --- a/src/ef/Properties/Resources.Designer.cs +++ b/src/ef/Properties/Resources.Designer.cs @@ -522,6 +522,18 @@ public static string RemainingArguments([CanBeNull] object remainingArguments) GetString("RemainingArguments", nameof(remainingArguments)), remainingArguments); + /// + /// Suppress generation of the DbContext.OnConfiguring() method. + /// + public static string SuppressOnConfiguringDescription + => GetString("SuppressOnConfiguringDescription"); + + /// + /// The DbContext.OnConfiguring() method will be generated. Potentially this contains sensitive information such as your connection string. You can suppress generation of this method using the --no-on-configuring option. See also http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. + /// + public static string OnConfiguringWarning + => GetString("OnConfiguringWarning"); + 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 afb2a1ce634..bfe7c069440 100644 --- a/src/ef/Properties/Resources.resx +++ b/src/ef/Properties/Resources.resx @@ -345,4 +345,10 @@ Remaining arguments: '{remainingArguments}'. + + Suppress generation of the DbContext.OnConfiguring() method. + + + The DbContext.OnConfiguring() method will be generated. Potentially this contains sensitive information such as your connection string. You can suppress generation of this method using the --no-on-configuring option. See also http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. + \ No newline at end of file diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpDbContextGeneratorTest.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpDbContextGeneratorTest.cs index 500c29714b6..bf03639d1a7 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpDbContextGeneratorTest.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpDbContextGeneratorTest.cs @@ -119,6 +119,48 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) model => Assert.Empty(model.GetEntityTypes())); } + [ConditionalFact] + public void SuppressOnConfiguring_works() + { + Test( + modelBuilder => { }, + new ModelCodeGenerationOptions { SuppressOnConfiguring = true }, + code => + { + Assert.Equal( + @"using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata; + +namespace TestNamespace +{ + public partial class TestDbContext : DbContext + { + public TestDbContext() + { + } + + public TestDbContext(DbContextOptions options) + : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + OnModelCreatingPartial(modelBuilder); + } + + partial void OnModelCreatingPartial(ModelBuilder modelBuilder); + } +} +", + code.ContextFile.Code, + ignoreLineEndingDifferences: true); + + Assert.Empty(code.AdditionalFiles); + }); + } + [ConditionalFact] public void Plugins_work() { diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/ModelCodeGeneratorTestBase.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/ModelCodeGeneratorTestBase.cs index e0bc1500fe8..c891cd7ab6b 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/ModelCodeGeneratorTestBase.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/ModelCodeGeneratorTestBase.cs @@ -15,6 +15,14 @@ namespace Microsoft.EntityFrameworkCore.Scaffolding.Internal { public abstract class ModelCodeGeneratorTestBase { + protected void Test( + Action buildModel, + ModelCodeGenerationOptions options, + Action assertScaffold) + { + Test(buildModel, options, assertScaffold, null); + } + protected void Test( Action buildModel, ModelCodeGenerationOptions options, @@ -61,8 +69,12 @@ protected void Test( var assembly = build.BuildInMemory(); var context = (DbContext)assembly.CreateInstance("TestNamespace.TestDbContext"); - var compiledModel = context.Model; - assertModel(compiledModel); + + if (assertModel != null) + { + var compiledModel = context.Model; + assertModel(compiledModel); + } } } } From 2db74578afacb6f7d3789eb385b3383d9b11c16d Mon Sep 17 00:00:00 2001 From: lajones Date: Mon, 11 May 2020 15:18:34 -0700 Subject: [PATCH 3/5] Change SuppressOnConfiguring to NoOnConfiguring. Change --no-on-configuring to --no-onconfiguring. --- src/EFCore.Tools/tools/EntityFrameworkCore.PS2.psm1 | 4 ++-- src/EFCore.Tools/tools/EntityFrameworkCore.psm1 | 8 ++++---- src/ef/Commands/DbContextScaffoldCommand.Configure.cs | 2 +- src/ef/Properties/Resources.Designer.cs | 2 +- src/ef/Properties/Resources.resx | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/EFCore.Tools/tools/EntityFrameworkCore.PS2.psm1 b/src/EFCore.Tools/tools/EntityFrameworkCore.PS2.psm1 index bebc4763db7..1392590c9b0 100644 --- a/src/EFCore.Tools/tools/EntityFrameworkCore.PS2.psm1 +++ b/src/EFCore.Tools/tools/EntityFrameworkCore.PS2.psm1 @@ -175,7 +175,7 @@ function Remove-Migration( .PARAMETER Force Overwrite existing files. -.PARAMETER SuppressOnConfiguring +.PARAMETER NoOnConfiguring Suppress generation of the DbContext.OnConfiguring() method. .PARAMETER Project @@ -204,7 +204,7 @@ function Scaffold-DbContext( [switch] $DataAnnotations, [switch] $UseDatabaseNames, [switch] $Force, - [switch] $SuppressOnConfiguring, + [switch] $NoOnConfiguring, $Project, $StartupProject, $Namespace, diff --git a/src/EFCore.Tools/tools/EntityFrameworkCore.psm1 b/src/EFCore.Tools/tools/EntityFrameworkCore.psm1 index 97ed4894ec1..7bfe3d69763 100644 --- a/src/EFCore.Tools/tools/EntityFrameworkCore.psm1 +++ b/src/EFCore.Tools/tools/EntityFrameworkCore.psm1 @@ -359,7 +359,7 @@ Register-TabExpansion Scaffold-DbContext @{ .PARAMETER Force Overwrite existing files. -.PARAMETER SuppressOnConfiguring +.PARAMETER NoOnConfiguring Suppress generation of the DbContext.OnConfiguring() method. .PARAMETER Project @@ -396,7 +396,7 @@ function Scaffold-DbContext [switch] $DataAnnotations, [switch] $UseDatabaseNames, [switch] $Force, - [switch] $SuppressOnConfiguring, + [switch] $NoOnConfiguring, [string] $Project, [string] $StartupProject, [string] $Namespace, @@ -452,9 +452,9 @@ function Scaffold-DbContext $params += '--force' } - if ($SuppressOnConfiguring) + if ($NoOnConfiguring) { - $params += '--no-on-configuring' + $params += '--no-onconfiguring' } if ($RemainingArguments -ne $null) diff --git a/src/ef/Commands/DbContextScaffoldCommand.Configure.cs b/src/ef/Commands/DbContextScaffoldCommand.Configure.cs index 72b98406778..63d6b189ec4 100644 --- a/src/ef/Commands/DbContextScaffoldCommand.Configure.cs +++ b/src/ef/Commands/DbContextScaffoldCommand.Configure.cs @@ -41,7 +41,7 @@ public override void Configure(CommandLineApplication command) _json = Json.ConfigureOption(command); _namespace = command.Option("-n|--namespace ", Resources.NamespaceDescription); _contextNamespace = command.Option("--context-namespace ", Resources.ContextNamespaceDescription); - _suppressOnConfiguring = command.Option("--no-on-configuring", Resources.SuppressOnConfiguringDescription); + _suppressOnConfiguring = command.Option("--no-onconfiguring", Resources.SuppressOnConfiguringDescription); base.Configure(command); } diff --git a/src/ef/Properties/Resources.Designer.cs b/src/ef/Properties/Resources.Designer.cs index 070c4bc70e8..8362ece80cf 100644 --- a/src/ef/Properties/Resources.Designer.cs +++ b/src/ef/Properties/Resources.Designer.cs @@ -529,7 +529,7 @@ public static string SuppressOnConfiguringDescription => GetString("SuppressOnConfiguringDescription"); /// - /// The DbContext.OnConfiguring() method will be generated. Potentially this contains sensitive information such as your connection string. You can suppress generation of this method using the --no-on-configuring option. See also http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. + /// The DbContext.OnConfiguring() method will be generated. Potentially this contains sensitive information such as your connection string. You can suppress generation of this method using the --no-onconfiguring option. See also http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. /// public static string OnConfiguringWarning => GetString("OnConfiguringWarning"); diff --git a/src/ef/Properties/Resources.resx b/src/ef/Properties/Resources.resx index bfe7c069440..cd9a6c238c1 100644 --- a/src/ef/Properties/Resources.resx +++ b/src/ef/Properties/Resources.resx @@ -349,6 +349,6 @@ Suppress generation of the DbContext.OnConfiguring() method. - The DbContext.OnConfiguring() method will be generated. Potentially this contains sensitive information such as your connection string. You can suppress generation of this method using the --no-on-configuring option. See also http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. + The DbContext.OnConfiguring() method will be generated. Potentially this contains sensitive information such as your connection string. You can suppress generation of this method using the --no-onconfiguring option. See also http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. \ No newline at end of file From fd81d6f8fff0ad2e32d87db4b881d15c2f2d5e0f Mon Sep 17 00:00:00 2001 From: lajones Date: Mon, 18 May 2020 14:11:54 -0700 Subject: [PATCH 4/5] Updating per remaining PR comments. --- src/EFCore.Design/Design/OperationExecutor.cs | 2 +- .../Properties/DesignStrings.Designer.cs | 8 +++++++- src/EFCore.Design/Properties/DesignStrings.resx | 5 ++++- .../Scaffolding/Internal/ReverseEngineerScaffolder.cs | 11 ++++++++++- src/ef/Commands/DbContextScaffoldCommand.cs | 5 ----- src/ef/Properties/Resources.Designer.cs | 6 ------ src/ef/Properties/Resources.resx | 3 --- .../Internal/CSharpEntityTypeGeneratorTest.cs | 2 +- 8 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/EFCore.Design/Design/OperationExecutor.cs b/src/EFCore.Design/Design/OperationExecutor.cs index c7b496803d7..bc7996021a9 100644 --- a/src/EFCore.Design/Design/OperationExecutor.cs +++ b/src/EFCore.Design/Design/OperationExecutor.cs @@ -471,7 +471,7 @@ public ScaffoldContext( var useDataAnnotations = (bool)args["useDataAnnotations"]; var overwriteFiles = (bool)args["overwriteFiles"]; var useDatabaseNames = (bool)args["useDatabaseNames"]; - var suppressOnConfiguring = (bool)args["suppressOnConfiguring"]; + var suppressOnConfiguring = (bool)(args["suppressOnConfiguring"] ?? false); Execute( () => executor.ScaffoldContextImpl( diff --git a/src/EFCore.Design/Properties/DesignStrings.Designer.cs b/src/EFCore.Design/Properties/DesignStrings.Designer.cs index 4a1c9b5e030..3faa4e0c850 100644 --- a/src/EFCore.Design/Properties/DesignStrings.Designer.cs +++ b/src/EFCore.Design/Properties/DesignStrings.Designer.cs @@ -299,7 +299,7 @@ public static string MigrationsAssemblyMismatch([CanBeNull] object assembly, [Ca assembly, migrationsAssembly); /// - /// To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. + /// To protect potentially sensitive information in your connection string, you should move it out of source code. You can use the Name= syntax - see https://go.microsoft.com/fwlink/?linkid=2131148. Or see http://go.microsoft.com/fwlink/?LinkId=723263 for more guidance on storing connection strings. /// public static string SensitiveInformationWarning => GetString("SensitiveInformationWarning"); @@ -634,6 +634,12 @@ public static string ConflictingContextAndMigrationName([CanBeNull] object name) GetString("ConflictingContextAndMigrationName", nameof(name)), name); + /// + /// The DbContext.OnConfiguring() method will be generated. Potentially this contains sensitive information such as your connection string. You can suppress generation of this method using the --no-onconfiguring option. See also http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. + /// + public static string OnConfiguringWarning + => GetString("OnConfiguringWarning"); + 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 3f361fa927c..1a9761add0e 100644 --- a/src/EFCore.Design/Properties/DesignStrings.resx +++ b/src/EFCore.Design/Properties/DesignStrings.resx @@ -231,7 +231,7 @@ Change your migrations assembly by using DbContextOptionsBuilder. E.g. options.U Change your target project to the migrations project by using the Package Manager Console's Default project drop-down list, or by executing "dotnet ef" from the directory containing the migrations project. - To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. + To protect potentially sensitive information in your connection string, you should move it out of source code. You can use the Name= syntax - see https://go.microsoft.com/fwlink/?linkid=2131148. Or see http://go.microsoft.com/fwlink/?LinkId=723263 for more guidance on storing connection strings. Localize the URL if we have localized docs. @@ -366,4 +366,7 @@ Change your target project to the migrations project by using the Package Manage The name you have chosen for the migration, '{name}', is the same as the context class name. Please choose a different name for your migration. Might we suggest 'InitialCreate' for your first migration? + + The DbContext.OnConfiguring() method will be generated. Potentially this contains sensitive information such as your connection string. You can suppress generation of this method using the --no-onconfiguring option. See also http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. + \ No newline at end of file diff --git a/src/EFCore.Design/Scaffolding/Internal/ReverseEngineerScaffolder.cs b/src/EFCore.Design/Scaffolding/Internal/ReverseEngineerScaffolder.cs index 1162b855613..d8c8d279444 100644 --- a/src/EFCore.Design/Scaffolding/Internal/ReverseEngineerScaffolder.cs +++ b/src/EFCore.Design/Scaffolding/Internal/ReverseEngineerScaffolder.cs @@ -9,6 +9,7 @@ using System.Text; using JetBrains.Annotations; using Microsoft.EntityFrameworkCore.Design; +using Microsoft.EntityFrameworkCore.Design.Internal; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata.Internal; @@ -32,6 +33,7 @@ public class ReverseEngineerScaffolder : IReverseEngineerScaffolder private readonly ICSharpUtilities _cSharpUtilities; private readonly ICSharpHelper _code; private readonly INamedConnectionStringResolver _connectionStringResolver; + private readonly IOperationReporter _reporter; private const string DbContextSuffix = "Context"; private const string DefaultDbContextName = "Model" + DbContextSuffix; @@ -47,7 +49,8 @@ public ReverseEngineerScaffolder( [NotNull] IModelCodeGeneratorSelector modelCodeGeneratorSelector, [NotNull] ICSharpUtilities cSharpUtilities, [NotNull] ICSharpHelper cSharpHelper, - [NotNull] INamedConnectionStringResolver connectionStringResolver) + [NotNull] INamedConnectionStringResolver connectionStringResolver, + [NotNull] IOperationReporter reporter) { Check.NotNull(databaseModelFactory, nameof(databaseModelFactory)); Check.NotNull(scaffoldingModelFactory, nameof(scaffoldingModelFactory)); @@ -55,6 +58,7 @@ public ReverseEngineerScaffolder( Check.NotNull(cSharpUtilities, nameof(cSharpUtilities)); Check.NotNull(cSharpHelper, nameof(cSharpHelper)); Check.NotNull(connectionStringResolver, nameof(connectionStringResolver)); + Check.NotNull(reporter, nameof(reporter)); _databaseModelFactory = databaseModelFactory; _factory = scaffoldingModelFactory; @@ -62,6 +66,7 @@ public ReverseEngineerScaffolder( _cSharpUtilities = cSharpUtilities; _code = cSharpHelper; _connectionStringResolver = connectionStringResolver; + _reporter = reporter; } /// @@ -102,6 +107,10 @@ public virtual ScaffoldedModel ScaffoldModel( { codeOptions.SuppressConnectionStringWarning = true; } + else + { + _reporter.WriteWarning(DesignStrings.OnConfiguringWarning); + } if (codeOptions.ConnectionString == null) { diff --git a/src/ef/Commands/DbContextScaffoldCommand.cs b/src/ef/Commands/DbContextScaffoldCommand.cs index 085bc8e8dd3..642c9346778 100644 --- a/src/ef/Commands/DbContextScaffoldCommand.cs +++ b/src/ef/Commands/DbContextScaffoldCommand.cs @@ -23,11 +23,6 @@ protected override void Validate() { throw new CommandException(Resources.MissingArgument(_provider.Name)); } - - if (!_suppressOnConfiguring.HasValue()) - { - Reporter.WriteWarning(Resources.OnConfiguringWarning); - } } protected override int Execute(string[] args) diff --git a/src/ef/Properties/Resources.Designer.cs b/src/ef/Properties/Resources.Designer.cs index 8362ece80cf..4eeed2ec9c8 100644 --- a/src/ef/Properties/Resources.Designer.cs +++ b/src/ef/Properties/Resources.Designer.cs @@ -528,12 +528,6 @@ public static string RemainingArguments([CanBeNull] object remainingArguments) public static string SuppressOnConfiguringDescription => GetString("SuppressOnConfiguringDescription"); - /// - /// The DbContext.OnConfiguring() method will be generated. Potentially this contains sensitive information such as your connection string. You can suppress generation of this method using the --no-onconfiguring option. See also http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. - /// - public static string OnConfiguringWarning - => GetString("OnConfiguringWarning"); - 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 cd9a6c238c1..608462eae96 100644 --- a/src/ef/Properties/Resources.resx +++ b/src/ef/Properties/Resources.resx @@ -348,7 +348,4 @@ Suppress generation of the DbContext.OnConfiguring() method. - - The DbContext.OnConfiguring() method will be generated. Potentially this contains sensitive information such as your connection string. You can suppress generation of this method using the --no-onconfiguring option. See also http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. - \ No newline at end of file diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpEntityTypeGeneratorTest.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpEntityTypeGeneratorTest.cs index 30081cdea26..365f6e7d4de 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpEntityTypeGeneratorTest.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpEntityTypeGeneratorTest.cs @@ -387,7 +387,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { -#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. +#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can use the Name= syntax - see https://go.microsoft.com/fwlink/?linkid=2131148. Or see http://go.microsoft.com/fwlink/?LinkId=723263 for more guidance on storing connection strings. optionsBuilder.UseSqlServer(""Initial Catalog=TestDatabase""); } } From 9e1af53b8c06a17bd30967fe42df2fcd1ef33795 Mon Sep 17 00:00:00 2001 From: lajones Date: Tue, 26 May 2020 21:45:34 -0700 Subject: [PATCH 5/5] Updated as requested. --- src/EFCore.Design/Properties/DesignStrings.Designer.cs | 8 +------- src/EFCore.Design/Properties/DesignStrings.resx | 5 +---- .../Scaffolding/Internal/ReverseEngineerScaffolder.cs | 4 ++-- .../Scaffolding/Internal/CSharpEntityTypeGeneratorTest.cs | 2 +- 4 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/EFCore.Design/Properties/DesignStrings.Designer.cs b/src/EFCore.Design/Properties/DesignStrings.Designer.cs index 3faa4e0c850..a696c8e5c84 100644 --- a/src/EFCore.Design/Properties/DesignStrings.Designer.cs +++ b/src/EFCore.Design/Properties/DesignStrings.Designer.cs @@ -299,7 +299,7 @@ public static string MigrationsAssemblyMismatch([CanBeNull] object assembly, [Ca assembly, migrationsAssembly); /// - /// To protect potentially sensitive information in your connection string, you should move it out of source code. You can use the Name= syntax - see https://go.microsoft.com/fwlink/?linkid=2131148. Or see http://go.microsoft.com/fwlink/?LinkId=723263 for more guidance on storing connection strings. + /// To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263. /// public static string SensitiveInformationWarning => GetString("SensitiveInformationWarning"); @@ -634,12 +634,6 @@ public static string ConflictingContextAndMigrationName([CanBeNull] object name) GetString("ConflictingContextAndMigrationName", nameof(name)), name); - /// - /// The DbContext.OnConfiguring() method will be generated. Potentially this contains sensitive information such as your connection string. You can suppress generation of this method using the --no-onconfiguring option. See also http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. - /// - public static string OnConfiguringWarning - => GetString("OnConfiguringWarning"); - 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 1a9761add0e..0ae9b9bdf09 100644 --- a/src/EFCore.Design/Properties/DesignStrings.resx +++ b/src/EFCore.Design/Properties/DesignStrings.resx @@ -231,7 +231,7 @@ Change your migrations assembly by using DbContextOptionsBuilder. E.g. options.U Change your target project to the migrations project by using the Package Manager Console's Default project drop-down list, or by executing "dotnet ef" from the directory containing the migrations project. - To protect potentially sensitive information in your connection string, you should move it out of source code. You can use the Name= syntax - see https://go.microsoft.com/fwlink/?linkid=2131148. Or see http://go.microsoft.com/fwlink/?LinkId=723263 for more guidance on storing connection strings. + To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263. Localize the URL if we have localized docs. @@ -366,7 +366,4 @@ Change your target project to the migrations project by using the Package Manage The name you have chosen for the migration, '{name}', is the same as the context class name. Please choose a different name for your migration. Might we suggest 'InitialCreate' for your first migration? - - The DbContext.OnConfiguring() method will be generated. Potentially this contains sensitive information such as your connection string. You can suppress generation of this method using the --no-onconfiguring option. See also http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. - \ No newline at end of file diff --git a/src/EFCore.Design/Scaffolding/Internal/ReverseEngineerScaffolder.cs b/src/EFCore.Design/Scaffolding/Internal/ReverseEngineerScaffolder.cs index d8c8d279444..5ab7443cdd1 100644 --- a/src/EFCore.Design/Scaffolding/Internal/ReverseEngineerScaffolder.cs +++ b/src/EFCore.Design/Scaffolding/Internal/ReverseEngineerScaffolder.cs @@ -107,9 +107,9 @@ public virtual ScaffoldedModel ScaffoldModel( { codeOptions.SuppressConnectionStringWarning = true; } - else + else if (!codeOptions.SuppressOnConfiguring) { - _reporter.WriteWarning(DesignStrings.OnConfiguringWarning); + _reporter.WriteWarning(DesignStrings.SensitiveInformationWarning); } if (codeOptions.ConnectionString == null) diff --git a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpEntityTypeGeneratorTest.cs b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpEntityTypeGeneratorTest.cs index 365f6e7d4de..4ca21b197b3 100644 --- a/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpEntityTypeGeneratorTest.cs +++ b/test/EFCore.Design.Tests/Scaffolding/Internal/CSharpEntityTypeGeneratorTest.cs @@ -387,7 +387,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { -#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can use the Name= syntax - see https://go.microsoft.com/fwlink/?linkid=2131148. Or see http://go.microsoft.com/fwlink/?LinkId=723263 for more guidance on storing connection strings. +#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263. optionsBuilder.UseSqlServer(""Initial Catalog=TestDatabase""); } }