diff --git a/src/EntityFramework.Core/DbContextOptions.cs b/src/EntityFramework.Core/DbContextOptions.cs index 82751400851..fb01072d9d3 100644 --- a/src/EntityFramework.Core/DbContextOptions.cs +++ b/src/EntityFramework.Core/DbContextOptions.cs @@ -22,7 +22,7 @@ public class DbContextOptions : IDbContextOptions public DbContextOptions() { _extensions = new List(); - _rawOptions = ImmutableDictionary.Empty; + _rawOptions = ImmutableDictionary.Empty.WithComparers(StringComparer.OrdinalIgnoreCase); } protected DbContextOptions([NotNull] DbContextOptions copyFrom) diff --git a/src/EntityFramework.Core/Infrastructure/DbContextOptionsParser.cs b/src/EntityFramework.Core/Infrastructure/DbContextOptionsParser.cs index 301c840f64e..f3989cc4cce 100644 --- a/src/EntityFramework.Core/Infrastructure/DbContextOptionsParser.cs +++ b/src/EntityFramework.Core/Infrastructure/DbContextOptionsParser.cs @@ -34,7 +34,7 @@ public virtual IReadOnlyDictionary ReadRawOptions( Check.NotNull(configuration, "configuration"); Check.NotNull(contextType, "contextType"); - var options = currentOptions.ToDictionary(i => i.Key, i => i.Value); + var options = currentOptions.ToDictionary(i => i.Key, i => i.Value, StringComparer.OrdinalIgnoreCase); ReadRawOptions(options, configuration, string.Concat( EntityFrameworkKey, Constants.KeyDelimiter, contextType.Name)); diff --git a/test/EntityFramework.Core.Tests/DbContextOptionsParserTest.cs b/test/EntityFramework.Core.Tests/DbContextOptionsParserTest.cs index 78c4986ba83..36c39e839d9 100644 --- a/test/EntityFramework.Core.Tests/DbContextOptionsParserTest.cs +++ b/test/EntityFramework.Core.Tests/DbContextOptionsParserTest.cs @@ -5,6 +5,7 @@ using Microsoft.Data.Entity.Infrastructure; using Microsoft.Framework.ConfigurationModel; using Xunit; +using System; namespace Microsoft.Data.Entity.Tests { @@ -21,7 +22,7 @@ public void Connection_string_is_found_using_context_name() } }; - var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, typeof(MyContext), new Dictionary()); + var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, typeof(MyContext), new Dictionary(StringComparer.OrdinalIgnoreCase)); Assert.Equal(1, rawOptions.Count); Assert.Equal("MyConnectionString", rawOptions["ConnectionString"]); @@ -38,7 +39,7 @@ public void Connection_string_is_found_using_context_full_name() } }; - var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, typeof(MyContext), new Dictionary()); + var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, typeof(MyContext), new Dictionary(StringComparer.OrdinalIgnoreCase)); Assert.Equal(1, rawOptions.Count); Assert.Equal("MyConnectionString", rawOptions["ConnectionString"]); @@ -55,7 +56,7 @@ public void Connection_string_is_found_using_context_name_generic() } }; - var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, new Dictionary()); + var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, new Dictionary(StringComparer.OrdinalIgnoreCase)); Assert.Equal(1, rawOptions.Count); Assert.Equal("MyConnectionString", rawOptions["ConnectionString"]); @@ -72,7 +73,7 @@ public void Connection_string_is_found_using_context_full_name_generic() } }; - var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, new Dictionary()); + var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, new Dictionary(StringComparer.OrdinalIgnoreCase)); Assert.Equal(1, rawOptions.Count); Assert.Equal("MyConnectionString", rawOptions["ConnectionString"]); @@ -94,7 +95,7 @@ public void Indirect_connection_string_is_found_using_context_name() } }; - var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, typeof(MyContext), new Dictionary()); + var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, typeof(MyContext), new Dictionary(StringComparer.OrdinalIgnoreCase)); Assert.Equal(1, rawOptions.Count); Assert.Equal("MyConnectionString", rawOptions["ConnectionString"]); @@ -112,7 +113,7 @@ public void Indirect_connection_string_is_found_using_context_full_name() } }; - var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, typeof(MyContext), new Dictionary()); + var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, typeof(MyContext), new Dictionary(StringComparer.OrdinalIgnoreCase)); Assert.Equal(1, rawOptions.Count); Assert.Equal("MyConnectionString", rawOptions["ConnectionString"]); @@ -130,7 +131,7 @@ public void Indirect_connection_string_is_found_using_context_name_generic() } }; - var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, new Dictionary()); + var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, new Dictionary(StringComparer.OrdinalIgnoreCase)); Assert.Equal(1, rawOptions.Count); Assert.Equal("MyConnectionString", rawOptions["ConnectionString"]); @@ -148,7 +149,7 @@ public void Indirect_connection_string_is_found_using_context_full_name_generic( } }; - var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, new Dictionary()); + var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, new Dictionary(StringComparer.OrdinalIgnoreCase)); Assert.Equal(1, rawOptions.Count); Assert.Equal("MyConnectionString", rawOptions["ConnectionString"]); @@ -165,7 +166,7 @@ public void Existing_options_are_updated() } }; - var currentOptions = new Dictionary { { "Foo", "Goo" } }; + var currentOptions = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "Foo", "Goo" } }; var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, typeof(MyContext), currentOptions); @@ -185,7 +186,7 @@ public void Existing_options_are_updated_generic() } }; - var currentOptions = new Dictionary { { "Foo", "Goo" } }; + var currentOptions = new Dictionary(StringComparer.OrdinalIgnoreCase) { { "Foo", "Goo" } }; var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, currentOptions); @@ -193,5 +194,22 @@ public void Existing_options_are_updated_generic() Assert.Equal("MyConnectionString", rawOptions["ConnectionString"]); Assert.Equal("Goo", rawOptions["Foo"]); } + + [Fact] + public void Key_searching_is_case_insensitive() { + var config = new Configuration + { + new MemoryConfigurationSource + { + { "entityFramework:" + typeof(MyContext).Name + ":connectionString", "MyConnectionString" } + } + }; + + var rawOptions = new DbContextOptionsParser().ReadRawOptions(config, typeof(MyContext), new Dictionary(StringComparer.OrdinalIgnoreCase)); + + Assert.Equal(1, rawOptions.Count); + Assert.Equal("MyConnectionString", rawOptions["ConnectionString"]); + } + } } diff --git a/test/EntityFramework.Core.Tests/DbContextTest.cs b/test/EntityFramework.Core.Tests/DbContextTest.cs index a00540b25c2..07d8559bb3d 100644 --- a/test/EntityFramework.Core.Tests/DbContextTest.cs +++ b/test/EntityFramework.Core.Tests/DbContextTest.cs @@ -1341,6 +1341,35 @@ public void Context_activation_reads_options_from_configuration_with_key_redirec } } + [Fact] + public void Context_activation_reads_options_from_configuration_case_insensitively() + { + var configSource = new MemoryConfigurationSource(); + configSource.Add("entityFramework:contextWithDefaults:connectionString", "MyConnectionString"); + + var config = new Configuration(); + config.Add(configSource); + + var services = new ServiceCollection(); + + services + .AddEntityFramework(config) + .AddDbContext(); + + var serviceProvider = services.BuildServiceProvider(); + + using (var context = serviceProvider.GetRequiredService()) + { + var contextServices = ((IDbContextServices)context).ScopedServiceProvider; + var contextOptions = (DbContextOptions)contextServices.GetRequiredService>().Service; + + Assert.NotNull(contextOptions); + var rawOptions = ((IDbContextOptions)contextOptions).RawOptions; + Assert.Equal(1, rawOptions.Count); + Assert.Equal("MyConnectionString", rawOptions["ConnectionString"]); + } + } + private class FakeService { }