From b4b0c72af4a7719213f709d98946c31aa8944f9d Mon Sep 17 00:00:00 2001 From: Andriy Svyryd Date: Fri, 7 Jan 2022 13:24:25 -0800 Subject: [PATCH] Use the default schema for migration data operations. Fixes #27100 --- .../Properties/AnalyzerStrings.Designer.cs | 60 +++++++++++++------ .../Migrations/MigrationsSqlGenerator.cs | 10 ++-- .../SqlServerMigrationsSqlGenerator.cs | 10 ++-- .../MigrationsSqlGeneratorTestBase.cs | 6 +- .../SqlServerMigrationsSqlGeneratorTest.cs | 30 +++++----- 5 files changed, 70 insertions(+), 46 deletions(-) diff --git a/src/EFCore.Analyzers/Properties/AnalyzerStrings.Designer.cs b/src/EFCore.Analyzers/Properties/AnalyzerStrings.Designer.cs index 74922826a46..e7e369733de 100644 --- a/src/EFCore.Analyzers/Properties/AnalyzerStrings.Designer.cs +++ b/src/EFCore.Analyzers/Properties/AnalyzerStrings.Designer.cs @@ -1,6 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -11,32 +12,46 @@ namespace Microsoft.EntityFrameworkCore { using System; - [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [System.Diagnostics.DebuggerNonUserCodeAttribute()] - [System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class AnalyzerStrings { - private static System.Resources.ResourceManager resourceMan; + private static global::System.Resources.ResourceManager resourceMan; - private static System.Globalization.CultureInfo resourceCulture; + private static global::System.Globalization.CultureInfo resourceCulture; - [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal AnalyzerStrings() { } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] - public static System.Resources.ResourceManager ResourceManager { + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { get { - if (object.Equals(null, resourceMan)) { - System.Resources.ResourceManager temp = new System.Resources.ResourceManager("Microsoft.EntityFrameworkCore.Properties.AnalyzerStrings", typeof(AnalyzerStrings).Assembly); + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.EntityFrameworkCore.Properties.AnalyzerStrings", typeof(AnalyzerStrings).Assembly); resourceMan = temp; } return resourceMan; } } - [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)] - public static System.Globalization.CultureInfo Culture { + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } @@ -45,22 +60,31 @@ public static System.Globalization.CultureInfo Culture { } } - public static string UninitializedDbSetWarningSuppressionJustification { - get { - return ResourceManager.GetString("UninitializedDbSetWarningSuppressionJustification", resourceCulture); - } - } - + /// + /// Looks up a localized string similar to {0} 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.. + /// public static string InternalUsageMessageFormat { get { return ResourceManager.GetString("InternalUsageMessageFormat", resourceCulture); } } + /// + /// Looks up a localized string similar to Internal EF Core API usage.. + /// public static string InternalUsageTitle { get { return ResourceManager.GetString("InternalUsageTitle", resourceCulture); } } + + /// + /// Looks up a localized string similar to DbSet properties on DbContext subclasses are automatically populated by the DbContext constructor.. + /// + public static string UninitializedDbSetWarningSuppressionJustification { + get { + return ResourceManager.GetString("UninitializedDbSetWarningSuppressionJustification", resourceCulture); + } + } } } diff --git a/src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs b/src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs index 351f7059004..f08c9c69118 100644 --- a/src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs +++ b/src/EFCore.Relational/Migrations/MigrationsSqlGenerator.cs @@ -861,7 +861,7 @@ protected virtual IEnumerable GenerateModification { throw new InvalidOperationException( RelationalStrings.InsertDataOperationValuesCountMismatch( - operation.Values.GetLength(1), operation.Columns.Length, FormatTable(operation.Table, operation.Schema))); + operation.Values.GetLength(1), operation.Columns.Length, FormatTable(operation.Table, operation.Schema ?? model?.GetDefaultSchema()))); } if (operation.ColumnTypes != null @@ -869,7 +869,7 @@ protected virtual IEnumerable GenerateModification { throw new InvalidOperationException( RelationalStrings.InsertDataOperationTypesCountMismatch( - operation.ColumnTypes.Length, operation.Columns.Length, FormatTable(operation.Table, operation.Schema))); + operation.ColumnTypes.Length, operation.Columns.Length, FormatTable(operation.Table, operation.Schema ?? model?.GetDefaultSchema()))); } if (operation.ColumnTypes == null @@ -877,7 +877,7 @@ protected virtual IEnumerable GenerateModification { throw new InvalidOperationException( RelationalStrings.InsertDataOperationNoModel( - FormatTable(operation.Table, operation.Schema))); + FormatTable(operation.Table, operation.Schema ?? model?.GetDefaultSchema()))); } var propertyMappings = operation.ColumnTypes == null @@ -887,7 +887,7 @@ protected virtual IEnumerable GenerateModification for (var i = 0; i < operation.Values.GetLength(0); i++) { var modificationCommand = Dependencies.ModificationCommandFactory.CreateModificationCommand( - new ModificationCommandParameters(operation.Table, operation.Schema, SensitiveLoggingEnabled)); + new ModificationCommandParameters(operation.Table, operation.Schema ?? model?.GetDefaultSchema(), SensitiveLoggingEnabled)); for (var j = 0; j < operation.Columns.Length; j++) { var name = operation.Columns[j]; @@ -1142,7 +1142,7 @@ private static IColumnMapping[] GetPropertyMappings( string? schema, IModel? model) { - var table = model?.GetRelationalModel().FindTable(tableName, schema); + var table = model?.GetRelationalModel().FindTable(tableName, schema ?? model.GetDefaultSchema()); if (table == null) { throw new InvalidOperationException( diff --git a/src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs b/src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs index d1c3360784e..255e4fdc683 100644 --- a/src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs +++ b/src/EFCore.SqlServer/Migrations/SqlServerMigrationsSqlGenerator.cs @@ -1374,7 +1374,7 @@ protected override void Generate( MigrationCommandListBuilder builder, bool terminate = true) { - GenerateIdentityInsert(builder, operation, on: true); + GenerateIdentityInsert(builder, operation, on: true, model); var sqlBuilder = new StringBuilder(); ((SqlServerUpdateSqlGenerator)Dependencies.UpdateSqlGenerator).AppendBulkInsertOperation( @@ -1395,7 +1395,7 @@ protected override void Generate( builder.Append(sqlBuilder.ToString()); } - GenerateIdentityInsert(builder, operation, on: false); + GenerateIdentityInsert(builder, operation, on: false, model); if (terminate) { @@ -1403,7 +1403,7 @@ protected override void Generate( } } - private void GenerateIdentityInsert(MigrationCommandListBuilder builder, InsertDataOperation operation, bool on) + private void GenerateIdentityInsert(MigrationCommandListBuilder builder, InsertDataOperation operation, bool on, IModel? model) { var stringTypeMapping = Dependencies.TypeMappingSource.GetMapping(typeof(string)); @@ -1414,14 +1414,14 @@ private void GenerateIdentityInsert(MigrationCommandListBuilder builder, InsertD .Append(") AND [object_id] = OBJECT_ID(") .Append( stringTypeMapping.GenerateSqlLiteral( - Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Table, operation.Schema))) + Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Table, operation.Schema ?? model?.GetDefaultSchema()))) .AppendLine("))"); using (builder.Indent()) { builder .Append("SET IDENTITY_INSERT ") - .Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Table, operation.Schema)) + .Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(operation.Table, operation.Schema ?? model?.GetDefaultSchema())) .Append(on ? " ON" : " OFF") .AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator); } diff --git a/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsSqlGeneratorTestBase.cs b/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsSqlGeneratorTestBase.cs index 5f5f4c61603..938a210e14e 100644 --- a/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsSqlGeneratorTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/Migrations/MigrationsSqlGeneratorTestBase.cs @@ -333,7 +333,7 @@ public void InsertDataOperation_throws_for_types_count_mismatch() [ConditionalFact] public void InsertDataOperation_throws_for_missing_entity_type() => Assert.Equal( - RelationalStrings.DataOperationNoTable("dbo.People"), + RelationalStrings.DataOperationNoTable("dbo1.People"), Assert.Throws( () => Generate( @@ -341,7 +341,7 @@ public void InsertDataOperation_throws_for_missing_entity_type() new InsertDataOperation { Table = "People", - Schema = "dbo", + Schema = "dbo1", Columns = new[] { "First Name" }, Values = new object[,] { { "John" } } })).Message); @@ -695,7 +695,7 @@ public virtual void DefaultValue_with_line_breaks(bool isUnicode) }); private static void CreateGotModel(ModelBuilder b) - => b.Entity( + => b.HasDefaultSchema("dbo").Entity( "Person", pb => { pb.ToTable("People"); diff --git a/test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs b/test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs index e3c5b3e16bf..37801b99558 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Migrations/SqlServerMigrationsSqlGeneratorTest.cs @@ -750,12 +750,12 @@ public override void InsertDataOperation_required_args() base.InsertDataOperation_required_args(); AssertSql( - @"IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'First Name') AND [object_id] = OBJECT_ID(N'[People]')) - SET IDENTITY_INSERT [People] ON; -INSERT INTO [People] ([First Name]) + @"IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'First Name') AND [object_id] = OBJECT_ID(N'[dbo].[People]')) + SET IDENTITY_INSERT [dbo].[People] ON; +INSERT INTO [dbo].[People] ([First Name]) VALUES (N'John'); -IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'First Name') AND [object_id] = OBJECT_ID(N'[People]')) - SET IDENTITY_INSERT [People] OFF; +IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'First Name') AND [object_id] = OBJECT_ID(N'[dbo].[People]')) + SET IDENTITY_INSERT [dbo].[People] OFF; "); } @@ -764,12 +764,12 @@ public override void InsertDataOperation_required_args_composite() base.InsertDataOperation_required_args_composite(); AssertSql( - @"IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'First Name', N'Last Name') AND [object_id] = OBJECT_ID(N'[People]')) - SET IDENTITY_INSERT [People] ON; -INSERT INTO [People] ([First Name], [Last Name]) + @"IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'First Name', N'Last Name') AND [object_id] = OBJECT_ID(N'[dbo].[People]')) + SET IDENTITY_INSERT [dbo].[People] ON; +INSERT INTO [dbo].[People] ([First Name], [Last Name]) VALUES (N'John', N'Snow'); -IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'First Name', N'Last Name') AND [object_id] = OBJECT_ID(N'[People]')) - SET IDENTITY_INSERT [People] OFF; +IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'First Name', N'Last Name') AND [object_id] = OBJECT_ID(N'[dbo].[People]')) + SET IDENTITY_INSERT [dbo].[People] OFF; "); } @@ -778,13 +778,13 @@ public override void InsertDataOperation_required_args_multiple_rows() base.InsertDataOperation_required_args_multiple_rows(); AssertSql( - @"IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'First Name') AND [object_id] = OBJECT_ID(N'[People]')) - SET IDENTITY_INSERT [People] ON; -INSERT INTO [People] ([First Name]) + @"IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'First Name') AND [object_id] = OBJECT_ID(N'[dbo].[People]')) + SET IDENTITY_INSERT [dbo].[People] ON; +INSERT INTO [dbo].[People] ([First Name]) VALUES (N'John'), (N'Daenerys'); -IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'First Name') AND [object_id] = OBJECT_ID(N'[People]')) - SET IDENTITY_INSERT [People] OFF; +IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'First Name') AND [object_id] = OBJECT_ID(N'[dbo].[People]')) + SET IDENTITY_INSERT [dbo].[People] OFF; "); }