From bf5caf50167f1097a4c5e09cf61633a4897ae55f Mon Sep 17 00:00:00 2001 From: Arthur Vickers Date: Fri, 15 Jul 2022 16:52:18 +0100 Subject: [PATCH] Allow null connection string to be passed to UseProvider methods Fixes #26869 --- ...ServerDbContextOptionsBuilderExtensions.cs | 6 ++---- .../SqlServerServiceCollectionExtensions.cs | 8 ++------ ...SqliteDbContextOptionsBuilderExtensions.cs | 6 ++---- .../SqliteServiceCollectionExtensions.cs | 8 ++------ .../TwoDatabasesTestBase.cs | 10 ++++++---- .../TwoDatabasesSqlServerTest.cs | 7 +++++-- ...SqlServerDbContextOptionsExtensionsTest.cs | 20 +++++++++++-------- .../TwoDatabasesSqliteTest.cs | 7 +++++-- ...teDbContextOptionsBuilderExtensionsTest.cs | 20 +++++++++++-------- 9 files changed, 48 insertions(+), 44 deletions(-) diff --git a/src/EFCore.SqlServer/Extensions/SqlServerDbContextOptionsBuilderExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerDbContextOptionsBuilderExtensions.cs index 11ba7325e66..16002a84623 100644 --- a/src/EFCore.SqlServer/Extensions/SqlServerDbContextOptionsBuilderExtensions.cs +++ b/src/EFCore.SqlServer/Extensions/SqlServerDbContextOptionsBuilderExtensions.cs @@ -62,11 +62,9 @@ public static DbContextOptionsBuilder UseSqlServer( /// The options builder so that further configuration can be chained. public static DbContextOptionsBuilder UseSqlServer( this DbContextOptionsBuilder optionsBuilder, - string connectionString, + string? connectionString, Action? sqlServerOptionsAction = null) { - Check.NotEmpty(connectionString, nameof(connectionString)); - var extension = (SqlServerOptionsExtension)GetOrCreateExtension(optionsBuilder).WithConnectionString(connectionString); ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension); @@ -152,7 +150,7 @@ public static DbContextOptionsBuilder UseSqlServer( /// The options builder so that further configuration can be chained. public static DbContextOptionsBuilder UseSqlServer( this DbContextOptionsBuilder optionsBuilder, - string connectionString, + string? connectionString, Action? sqlServerOptionsAction = null) where TContext : DbContext => (DbContextOptionsBuilder)UseSqlServer( diff --git a/src/EFCore.SqlServer/Extensions/SqlServerServiceCollectionExtensions.cs b/src/EFCore.SqlServer/Extensions/SqlServerServiceCollectionExtensions.cs index 7a4587438c6..63f8284b289 100644 --- a/src/EFCore.SqlServer/Extensions/SqlServerServiceCollectionExtensions.cs +++ b/src/EFCore.SqlServer/Extensions/SqlServerServiceCollectionExtensions.cs @@ -57,20 +57,16 @@ public static class SqlServerServiceCollectionExtensions /// The same service collection so that multiple calls can be chained. public static IServiceCollection AddSqlServer( this IServiceCollection serviceCollection, - string connectionString, + string? connectionString, Action? sqlServerOptionsAction = null, Action? optionsAction = null) where TContext : DbContext - { - Check.NotEmpty(connectionString, nameof(connectionString)); - - return serviceCollection.AddDbContext( + => serviceCollection.AddDbContext( (_, options) => { optionsAction?.Invoke(options); options.UseSqlServer(connectionString, sqlServerOptionsAction); }); - } /// /// diff --git a/src/EFCore.Sqlite.Core/Extensions/SqliteDbContextOptionsBuilderExtensions.cs b/src/EFCore.Sqlite.Core/Extensions/SqliteDbContextOptionsBuilderExtensions.cs index e0a041e5125..e3563c62da3 100644 --- a/src/EFCore.Sqlite.Core/Extensions/SqliteDbContextOptionsBuilderExtensions.cs +++ b/src/EFCore.Sqlite.Core/Extensions/SqliteDbContextOptionsBuilderExtensions.cs @@ -59,11 +59,9 @@ public static DbContextOptionsBuilder UseSqlite( /// The options builder so that further configuration can be chained. public static DbContextOptionsBuilder UseSqlite( this DbContextOptionsBuilder optionsBuilder, - string connectionString, + string? connectionString, Action? sqliteOptionsAction = null) { - Check.NotEmpty(connectionString, nameof(connectionString)); - var extension = (SqliteOptionsExtension)GetOrCreateExtension(optionsBuilder).WithConnectionString(connectionString); ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension); @@ -145,7 +143,7 @@ public static DbContextOptionsBuilder UseSqlite( /// The options builder so that further configuration can be chained. public static DbContextOptionsBuilder UseSqlite( this DbContextOptionsBuilder optionsBuilder, - string connectionString, + string? connectionString, Action? sqliteOptionsAction = null) where TContext : DbContext => (DbContextOptionsBuilder)UseSqlite( diff --git a/src/EFCore.Sqlite.Core/Extensions/SqliteServiceCollectionExtensions.cs b/src/EFCore.Sqlite.Core/Extensions/SqliteServiceCollectionExtensions.cs index 4f3a76f7460..05cc828579d 100644 --- a/src/EFCore.Sqlite.Core/Extensions/SqliteServiceCollectionExtensions.cs +++ b/src/EFCore.Sqlite.Core/Extensions/SqliteServiceCollectionExtensions.cs @@ -55,20 +55,16 @@ public static class SqliteServiceCollectionExtensions /// The same service collection so that multiple calls can be chained. public static IServiceCollection AddSqlite( this IServiceCollection serviceCollection, - string connectionString, + string? connectionString, Action? sqliteOptionsAction = null, Action? optionsAction = null) where TContext : DbContext - { - Check.NotEmpty(connectionString, nameof(connectionString)); - - return serviceCollection.AddDbContext( + => serviceCollection.AddDbContext( (_, options) => { optionsAction?.Invoke(options); options.UseSqlite(connectionString, sqliteOptionsAction); }); - } /// /// diff --git a/test/EFCore.Relational.Specification.Tests/TwoDatabasesTestBase.cs b/test/EFCore.Relational.Specification.Tests/TwoDatabasesTestBase.cs index 7f73a84a68b..badb0255ce3 100644 --- a/test/EFCore.Relational.Specification.Tests/TwoDatabasesTestBase.cs +++ b/test/EFCore.Relational.Specification.Tests/TwoDatabasesTestBase.cs @@ -74,9 +74,10 @@ public virtual void Can_query_from_one_connection_and_save_changes_to_another() } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Can_set_connection_string_in_interceptor(bool withConnectionString) + [InlineData(true, false)] + [InlineData(true, false)] + [InlineData(true, true)] + public virtual void Can_set_connection_string_in_interceptor(bool withConnectionString, bool withNullConnectionString) { using var context1 = CreateBackingContext("TwoDatabasesIntercept"); @@ -132,7 +133,8 @@ public override void ConnectionClosed(DbConnection connection, ConnectionEndEven protected abstract DbContextOptionsBuilder CreateTestOptions( DbContextOptionsBuilder optionsBuilder, - bool withConnectionString = false); + bool withConnectionString = false, + bool withNullConnectionString = false); protected abstract TwoDatabasesWithDataContext CreateBackingContext(string databaseName); diff --git a/test/EFCore.SqlServer.FunctionalTests/TwoDatabasesSqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/TwoDatabasesSqlServerTest.cs index 6eee3a0296e..14766fcff77 100644 --- a/test/EFCore.SqlServer.FunctionalTests/TwoDatabasesSqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/TwoDatabasesSqlServerTest.cs @@ -15,9 +15,12 @@ public TwoDatabasesSqlServerTest(SqlServerFixture fixture) protected override DbContextOptionsBuilder CreateTestOptions( DbContextOptionsBuilder optionsBuilder, - bool withConnectionString = false) + bool withConnectionString = false, + bool withNullConnectionString = false) => withConnectionString - ? optionsBuilder.UseSqlServer(DummyConnectionString) + ? withNullConnectionString + ? optionsBuilder.UseSqlServer((string)null) + : optionsBuilder.UseSqlServer(DummyConnectionString) : optionsBuilder.UseSqlServer(); protected override TwoDatabasesWithDataContext CreateBackingContext(string databaseName) diff --git a/test/EFCore.SqlServer.Tests/SqlServerDbContextOptionsExtensionsTest.cs b/test/EFCore.SqlServer.Tests/SqlServerDbContextOptionsExtensionsTest.cs index fda169690f3..bd8d9d91702 100644 --- a/test/EFCore.SqlServer.Tests/SqlServerDbContextOptionsExtensionsTest.cs +++ b/test/EFCore.SqlServer.Tests/SqlServerDbContextOptionsExtensionsTest.cs @@ -43,15 +43,17 @@ public void Can_add_extension_with_connection_string() Assert.Null(extension.Connection); } - [ConditionalFact] - public void Can_add_extension_with_connection_string_using_generic_options() + [ConditionalTheory] + [InlineData(false)] + [InlineData(true)] + public void Can_add_extension_with_connection_string_using_generic_options(bool nullConnectionString) { var optionsBuilder = new DbContextOptionsBuilder(); - optionsBuilder.UseSqlServer("Database=Whisper"); + optionsBuilder.UseSqlServer(nullConnectionString ? null : "Database=Whisper"); var extension = optionsBuilder.Options.Extensions.OfType().Single(); - Assert.Equal("Database=Whisper", extension.ConnectionString); + Assert.Equal(nullConnectionString ? null : "Database=Whisper", extension.ConnectionString); Assert.Null(extension.Connection); } @@ -83,12 +85,14 @@ public void Can_add_extension_with_connection_using_generic_options() Assert.Null(extension.ConnectionString); } - [ConditionalFact] - public void Service_collection_extension_method_can_configure_sqlserver_options() + [ConditionalTheory] + [InlineData(false)] + [InlineData(true)] + public void Service_collection_extension_method_can_configure_sqlserver_options(bool nullConnectionString) { var serviceCollection = new ServiceCollection(); serviceCollection.AddSqlServer( - "Database=Crunchie", + nullConnectionString ? null : "Database=Crunchie", sqlServerOption => { sqlServerOption.MaxBatchSize(123); @@ -115,7 +119,7 @@ public void Service_collection_extension_method_can_configure_sqlserver_options( Assert.Equal(123, sqlServerOptions.MaxBatchSize); Assert.Equal(30, sqlServerOptions.CommandTimeout); - Assert.Equal("Database=Crunchie", sqlServerOptions.ConnectionString); + Assert.Equal(nullConnectionString ? null : "Database=Crunchie", sqlServerOptions.ConnectionString); } } diff --git a/test/EFCore.Sqlite.FunctionalTests/TwoDatabasesSqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/TwoDatabasesSqliteTest.cs index 42eeb94b195..5394861e540 100644 --- a/test/EFCore.Sqlite.FunctionalTests/TwoDatabasesSqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/TwoDatabasesSqliteTest.cs @@ -15,9 +15,12 @@ public TwoDatabasesSqliteTest(TwoDatabasesFixture fixture) protected override DbContextOptionsBuilder CreateTestOptions( DbContextOptionsBuilder optionsBuilder, - bool withConnectionString = false) + bool withConnectionString = false, + bool withNullConnectionString = false) => withConnectionString - ? optionsBuilder.UseSqlite(DummyConnectionString) + ? withNullConnectionString + ? optionsBuilder.UseSqlite((string)null) + : optionsBuilder.UseSqlite(DummyConnectionString) : optionsBuilder.UseSqlite(); protected override TwoDatabasesWithDataContext CreateBackingContext(string databaseName) diff --git a/test/EFCore.Sqlite.Tests/SqliteDbContextOptionsBuilderExtensionsTest.cs b/test/EFCore.Sqlite.Tests/SqliteDbContextOptionsBuilderExtensionsTest.cs index 21baae2c392..bc319faa7ee 100644 --- a/test/EFCore.Sqlite.Tests/SqliteDbContextOptionsBuilderExtensionsTest.cs +++ b/test/EFCore.Sqlite.Tests/SqliteDbContextOptionsBuilderExtensionsTest.cs @@ -42,15 +42,17 @@ public void Can_add_extension_with_connection_string() Assert.Null(extension.Connection); } - [ConditionalFact] - public void Can_add_extension_with_connection_string_using_generic_options() + [ConditionalTheory] + [InlineData(false)] + [InlineData(true)] + public void Can_add_extension_with_connection_string_using_generic_options(bool nullConnectionString) { var optionsBuilder = new DbContextOptionsBuilder(); - optionsBuilder.UseSqlite("Database=Whisper"); + optionsBuilder.UseSqlite(nullConnectionString ? null : "Database=Whisper"); var extension = optionsBuilder.Options.Extensions.OfType().Single(); - Assert.Equal("Database=Whisper", extension.ConnectionString); + Assert.Equal(nullConnectionString ? null : "Database=Whisper", extension.ConnectionString); Assert.Null(extension.Connection); } @@ -95,12 +97,14 @@ public void Can_add_extension_with_connection_using_generic_options() Assert.Null(extension.ConnectionString); } - [ConditionalFact] - public void Service_collection_extension_method_can_configure_sqlite_options() + [ConditionalTheory] + [InlineData(false)] + [InlineData(true)] + public void Service_collection_extension_method_can_configure_sqlite_options(bool nullConnectionString) { var serviceCollection = new ServiceCollection(); serviceCollection.AddSqlite( - "Database=Crunchie", + nullConnectionString ? null : "Database=Crunchie", sqliteOptions => { sqliteOptions.MaxBatchSize(123); @@ -127,7 +131,7 @@ public void Service_collection_extension_method_can_configure_sqlite_options() Assert.Equal(123, sqliteOptions.MaxBatchSize); Assert.Equal(30, sqliteOptions.CommandTimeout); - Assert.Equal("Database=Crunchie", sqliteOptions.ConnectionString); + Assert.Equal(nullConnectionString ? null : "Database=Crunchie", sqliteOptions.ConnectionString); } }