diff --git a/EFCore.NamingConventions.Test/LowerCaseNamingTest.cs b/EFCore.NamingConventions.Test/LowerCaseNamingTest.cs index fd31188..7b100de 100644 --- a/EFCore.NamingConventions.Test/LowerCaseNamingTest.cs +++ b/EFCore.NamingConventions.Test/LowerCaseNamingTest.cs @@ -1,3 +1,4 @@ +using System.Globalization; using System.Linq; using Microsoft.EntityFrameworkCore; using Xunit; @@ -23,6 +24,24 @@ namespace EFCore.NamingConventions.Test Assert.Equal("fullname", entityType.FindProperty("FullName").GetColumnName()); } + [Fact] + public void Column_name_is_rewritten_in_turkish() + { + using var context = CreateContext(CultureInfo.CreateSpecificCulture("tr_TR")); + var entityType = context.Model.FindEntityType(typeof(SimpleBlog)); + Assert.Equal("ıd", entityType.FindProperty("Id").GetColumnName()); + Assert.Equal("fullname", entityType.FindProperty("FullName").GetColumnName()); + } + + [Fact] + public void Column_name_is_rewritten_in_invariant() + { + using var context = CreateContext(CultureInfo.InvariantCulture); + var entityType = context.Model.FindEntityType(typeof(SimpleBlog)); + Assert.Equal("id", entityType.FindProperty("Id").GetColumnName()); + Assert.Equal("fullname", entityType.FindProperty("FullName").GetColumnName()); + } + [Fact] public void Primary_key_name_is_rewritten() { @@ -55,6 +74,6 @@ namespace EFCore.NamingConventions.Test Assert.Equal("ix_simpleblog_fullname", entityType.GetIndexes().Single().GetName()); } - TestContext CreateContext() => new TestContext(NamingConventionsExtensions.UseLowerCaseNamingConvention); + TestContext CreateContext(CultureInfo culture = null) => new TestContext(builder => builder.UseLowerCaseNamingConvention(culture)); } } diff --git a/EFCore.NamingConventions.Test/RewriterTestBase.cs b/EFCore.NamingConventions.Test/RewriterTestBase.cs index 93b9d79..177a403 100644 --- a/EFCore.NamingConventions.Test/RewriterTestBase.cs +++ b/EFCore.NamingConventions.Test/RewriterTestBase.cs @@ -9,8 +9,7 @@ namespace EFCore.NamingConventions.Test public class TestContext : DbContext { readonly Func _useNamingConvention; - - public TestContext(Func useNamingConvention) + public TestContext(Func useNamingConvention) => _useNamingConvention = useNamingConvention; public DbSet Blog { get; set; } diff --git a/EFCore.NamingConventions.Test/SnakeCaseNamingTest.cs b/EFCore.NamingConventions.Test/SnakeCaseNamingTest.cs index a292457..c1addfd 100644 --- a/EFCore.NamingConventions.Test/SnakeCaseNamingTest.cs +++ b/EFCore.NamingConventions.Test/SnakeCaseNamingTest.cs @@ -1,3 +1,4 @@ +using System.Globalization; using System.Linq; using Microsoft.EntityFrameworkCore; using Xunit; @@ -23,6 +24,24 @@ namespace EFCore.NamingConventions.Test Assert.Equal("full_name", entityType.FindProperty("FullName").GetColumnName()); } + [Fact] + public void Column_name_is_rewritten_in_turkish() + { + using var context = CreateContext(CultureInfo.CreateSpecificCulture("tr_TR")); + var entityType = context.Model.FindEntityType(typeof(SimpleBlog)); + Assert.Equal("ıd", entityType.FindProperty("Id").GetColumnName()); + Assert.Equal("full_name", entityType.FindProperty("FullName").GetColumnName()); + } + + [Fact] + public void Column_name_is_rewritten_in_invariant() + { + using var context = CreateContext(CultureInfo.InvariantCulture); + var entityType = context.Model.FindEntityType(typeof(SimpleBlog)); + Assert.Equal("id", entityType.FindProperty("Id").GetColumnName()); + Assert.Equal("full_name", entityType.FindProperty("FullName").GetColumnName()); + } + [Fact] public void Owned_entity_name_is_correct_when_configured() { @@ -63,6 +82,6 @@ namespace EFCore.NamingConventions.Test Assert.Equal("ix_simple_blog_full_name", entityType.GetIndexes().Single().GetName()); } - TestContext CreateContext() => new TestContext(NamingConventionsExtensions.UseSnakeCaseNamingConvention); + TestContext CreateContext(CultureInfo culture = null) => new TestContext(builder => builder.UseSnakeCaseNamingConvention(culture)); } } diff --git a/EFCore.NamingConventions.Test/UpperCaseNamingTest.cs b/EFCore.NamingConventions.Test/UpperCaseNamingTest.cs index 02647d2..0e1488e 100644 --- a/EFCore.NamingConventions.Test/UpperCaseNamingTest.cs +++ b/EFCore.NamingConventions.Test/UpperCaseNamingTest.cs @@ -1,3 +1,4 @@ +using System.Globalization; using System.Linq; using Microsoft.EntityFrameworkCore; using Xunit; @@ -14,6 +15,22 @@ namespace EFCore.NamingConventions.Test Assert.Equal("SIMPLEBLOG", entityType.GetTableName()); } + [Fact] + public void Table_name_is_rewritten_in_turkish() + { + using var context = CreateContext(CultureInfo.CreateSpecificCulture("tr_TR")); + var entityType = context.Model.FindEntityType(typeof(SimpleBlog)); + Assert.Equal("SİMPLEBLOG", entityType.GetTableName()); + } + + [Fact] + public void Table_name_is_rewritten_in_invariant() + { + using var context = CreateContext(CultureInfo.InvariantCulture); + var entityType = context.Model.FindEntityType(typeof(SimpleBlog)); + Assert.Equal("SIMPLEBLOG", entityType.GetTableName()); + } + [Fact] public void Column_name_is_rewritten() { @@ -55,6 +72,6 @@ namespace EFCore.NamingConventions.Test Assert.Equal("IX_SIMPLEBLOG_FULLNAME", entityType.GetIndexes().Single().GetName()); } - TestContext CreateContext() => new TestContext(NamingConventionsExtensions.UseUpperCaseNamingConvention); + TestContext CreateContext(CultureInfo culture = null) => new TestContext(builder => builder.UseUpperCaseNamingConvention(culture)); } } diff --git a/EFCore.NamingConventions/NamingConventions/Internal/LowerCaseNameRewriter.cs b/EFCore.NamingConventions/NamingConventions/Internal/LowerCaseNameRewriter.cs index f828f1a..a9dcb85 100644 --- a/EFCore.NamingConventions/NamingConventions/Internal/LowerCaseNameRewriter.cs +++ b/EFCore.NamingConventions/NamingConventions/Internal/LowerCaseNameRewriter.cs @@ -1,7 +1,12 @@ +using System.Globalization; + namespace EFCore.NamingConventions.Internal { class LowerCaseNameRewriter : NameRewriterBase { - protected override string RewriteName(string name) => name.ToLowerInvariant(); + readonly CultureInfo _culture; + + public LowerCaseNameRewriter(CultureInfo culture) => _culture = culture; + protected override string RewriteName(string name) => name.ToLower(_culture); } } diff --git a/EFCore.NamingConventions/NamingConventions/Internal/NameRewriterBase.cs b/EFCore.NamingConventions/NamingConventions/Internal/NameRewriterBase.cs index 3737ff6..5dc600d 100644 --- a/EFCore.NamingConventions/NamingConventions/Internal/NameRewriterBase.cs +++ b/EFCore.NamingConventions/NamingConventions/Internal/NameRewriterBase.cs @@ -1,5 +1,4 @@ using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Metadata.Conventions; diff --git a/EFCore.NamingConventions/NamingConventions/Internal/NamingConventionSetPlugin.cs b/EFCore.NamingConventions/NamingConventions/Internal/NamingConventionSetPlugin.cs index 7fa2ee9..5e88540 100644 --- a/EFCore.NamingConventions/NamingConventions/Internal/NamingConventionSetPlugin.cs +++ b/EFCore.NamingConventions/NamingConventions/Internal/NamingConventionSetPlugin.cs @@ -1,4 +1,5 @@ using System; +using System.Globalization; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Conventions; using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure; @@ -9,21 +10,20 @@ namespace EFCore.NamingConventions.Internal public class NamingConventionSetPlugin : IConventionSetPlugin { readonly IDbContextOptions _options; - public NamingConventionSetPlugin([NotNull] IDbContextOptions options) => _options = options; public ConventionSet ModifyConventions(ConventionSet conventionSet) { - var namingStyle = _options.FindExtension().NamingConvention; - + var extension = _options.FindExtension(); + var namingStyle = extension.NamingConvention; + var culture = extension.Culture; if (namingStyle == NamingConvention.None) return conventionSet; - NameRewriterBase nameRewriter = namingStyle switch { - NamingConvention.SnakeCase => new SnakeCaseNameRewriter(), - NamingConvention.LowerCase => new LowerCaseNameRewriter(), - NamingConvention.UpperCase => new UpperCaseNameRewriter(), + NamingConvention.SnakeCase => new SnakeCaseNameRewriter(culture ?? CultureInfo.InvariantCulture), + NamingConvention.LowerCase => new LowerCaseNameRewriter(culture ?? CultureInfo.InvariantCulture), + NamingConvention.UpperCase => new UpperCaseNameRewriter(culture ?? CultureInfo.InvariantCulture), _ => throw new NotImplementedException("Unhandled enum value: " + namingStyle) }; diff --git a/EFCore.NamingConventions/NamingConventions/Internal/NamingConventionsOptionsExtension.cs b/EFCore.NamingConventions/NamingConventions/Internal/NamingConventionsOptionsExtension.cs index e33fc00..8e3bb43 100644 --- a/EFCore.NamingConventions/NamingConventions/Internal/NamingConventionsOptionsExtension.cs +++ b/EFCore.NamingConventions/NamingConventions/Internal/NamingConventionsOptionsExtension.cs @@ -11,17 +11,21 @@ namespace EFCore.NamingConventions.Internal { DbContextOptionsExtensionInfo _info; NamingConvention _namingConvention; + CultureInfo _culture; public NamingConventionsOptionsExtension() {} - protected NamingConventionsOptionsExtension([NotNull] NamingConventionsOptionsExtension copyFrom) - => _namingConvention = copyFrom._namingConvention; + { + _namingConvention = copyFrom._namingConvention; + _culture = copyFrom._culture; + } public virtual DbContextOptionsExtensionInfo Info => _info ??= new ExtensionInfo(this); protected virtual NamingConventionsOptionsExtension Clone() => new NamingConventionsOptionsExtension(this); internal virtual NamingConvention NamingConvention => _namingConvention; + internal virtual CultureInfo Culture => _culture; public virtual NamingConventionsOptionsExtension WithoutNaming() { @@ -30,24 +34,27 @@ namespace EFCore.NamingConventions.Internal return clone; } - public virtual NamingConventionsOptionsExtension WithSnakeCaseNamingConvention() + public virtual NamingConventionsOptionsExtension WithSnakeCaseNamingConvention(CultureInfo culture = null) { var clone = Clone(); clone._namingConvention = NamingConvention.SnakeCase; + clone._culture = culture; return clone; } - public virtual NamingConventionsOptionsExtension WithLowerCaseNamingConvention() + public virtual NamingConventionsOptionsExtension WithLowerCaseNamingConvention(CultureInfo culture = null) { var clone = Clone(); clone._namingConvention = NamingConvention.LowerCase; + clone._culture = culture; return clone; } - public virtual NamingConventionsOptionsExtension WithUpperCaseNamingConvention() + public virtual NamingConventionsOptionsExtension WithUpperCaseNamingConvention(CultureInfo culture = null) { var clone = Clone(); clone._namingConvention = NamingConvention.UpperCase; + clone._culture = culture; return clone; } diff --git a/EFCore.NamingConventions/NamingConventions/Internal/SnakeCaseNameRewriter.cs b/EFCore.NamingConventions/NamingConventions/Internal/SnakeCaseNameRewriter.cs index 478de0e..210ea2e 100644 --- a/EFCore.NamingConventions/NamingConventions/Internal/SnakeCaseNameRewriter.cs +++ b/EFCore.NamingConventions/NamingConventions/Internal/SnakeCaseNameRewriter.cs @@ -6,6 +6,10 @@ namespace EFCore.NamingConventions.Internal { class SnakeCaseNameRewriter : NameRewriterBase { + private readonly CultureInfo _culture; + + public SnakeCaseNameRewriter(CultureInfo culture) => _culture = culture; + protected override string RewriteName(string name) { if (string.IsNullOrEmpty(name)) @@ -40,7 +44,7 @@ namespace EFCore.NamingConventions.Internal builder.Append('_'); } - currentChar = char.ToLower(currentChar); + currentChar = char.ToLower(currentChar, _culture); break; case UnicodeCategory.LowercaseLetter: diff --git a/EFCore.NamingConventions/NamingConventions/Internal/UpperCaseNameRewriter.cs b/EFCore.NamingConventions/NamingConventions/Internal/UpperCaseNameRewriter.cs index 3098609..0a8fd67 100644 --- a/EFCore.NamingConventions/NamingConventions/Internal/UpperCaseNameRewriter.cs +++ b/EFCore.NamingConventions/NamingConventions/Internal/UpperCaseNameRewriter.cs @@ -1,7 +1,12 @@ +using System.Globalization; + namespace EFCore.NamingConventions.Internal { class UpperCaseNameRewriter : NameRewriterBase { - protected override string RewriteName(string name) => name.ToUpperInvariant(); + readonly CultureInfo _culture; + + public UpperCaseNameRewriter(CultureInfo culture) => _culture = culture; + protected override string RewriteName(string name) => name.ToUpper(_culture); } } diff --git a/EFCore.NamingConventions/NamingConventionsExtensions.cs b/EFCore.NamingConventions/NamingConventionsExtensions.cs index 72c9c95..a08d224 100644 --- a/EFCore.NamingConventions/NamingConventionsExtensions.cs +++ b/EFCore.NamingConventions/NamingConventionsExtensions.cs @@ -1,3 +1,4 @@ +using System.Globalization; using Microsoft.EntityFrameworkCore.Infrastructure; using JetBrains.Annotations; using EFCore.NamingConventions.Internal; @@ -7,52 +8,52 @@ namespace Microsoft.EntityFrameworkCore { public static class NamingConventionsExtensions { - public static DbContextOptionsBuilder UseSnakeCaseNamingConvention([NotNull] this DbContextOptionsBuilder optionsBuilder) + public static DbContextOptionsBuilder UseSnakeCaseNamingConvention([NotNull] this DbContextOptionsBuilder optionsBuilder , CultureInfo culture = null) { Check.NotNull(optionsBuilder, nameof(optionsBuilder)); var extension = (optionsBuilder.Options.FindExtension() ?? new NamingConventionsOptionsExtension()) - .WithSnakeCaseNamingConvention(); + .WithSnakeCaseNamingConvention(culture); ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension); return optionsBuilder; } - public static DbContextOptionsBuilder UseSnakeCaseNamingConvention([NotNull] this DbContextOptionsBuilder optionsBuilder) + public static DbContextOptionsBuilder UseSnakeCaseNamingConvention([NotNull] this DbContextOptionsBuilder optionsBuilder , CultureInfo culture = null) where TContext : DbContext - => (DbContextOptionsBuilder)UseSnakeCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder); + => (DbContextOptionsBuilder)UseSnakeCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder,culture); - public static DbContextOptionsBuilder UseLowerCaseNamingConvention([NotNull] this DbContextOptionsBuilder optionsBuilder) + public static DbContextOptionsBuilder UseLowerCaseNamingConvention([NotNull] this DbContextOptionsBuilder optionsBuilder, CultureInfo culture = null) { Check.NotNull(optionsBuilder, nameof(optionsBuilder)); var extension = (optionsBuilder.Options.FindExtension() ?? new NamingConventionsOptionsExtension()) - .WithLowerCaseNamingConvention(); + .WithLowerCaseNamingConvention(culture); ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension); return optionsBuilder; } - public static DbContextOptionsBuilder UseLowerCaseNamingConvention([NotNull] this DbContextOptionsBuilder optionsBuilder) + public static DbContextOptionsBuilder UseLowerCaseNamingConvention([NotNull] this DbContextOptionsBuilder optionsBuilder, CultureInfo culture = null) where TContext : DbContext - => (DbContextOptionsBuilder)UseLowerCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder); + => (DbContextOptionsBuilder)UseLowerCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder,culture); - public static DbContextOptionsBuilder UseUpperCaseNamingConvention([NotNull] this DbContextOptionsBuilder optionsBuilder) + public static DbContextOptionsBuilder UseUpperCaseNamingConvention([NotNull] this DbContextOptionsBuilder optionsBuilder, CultureInfo culture = null) { Check.NotNull(optionsBuilder, nameof(optionsBuilder)); var extension = (optionsBuilder.Options.FindExtension() ?? new NamingConventionsOptionsExtension()) - .WithUpperCaseNamingConvention(); + .WithUpperCaseNamingConvention(culture); ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension); return optionsBuilder; } - public static DbContextOptionsBuilder UseUpperCaseNamingConvention([NotNull] this DbContextOptionsBuilder optionsBuilder) + public static DbContextOptionsBuilder UseUpperCaseNamingConvention([NotNull] this DbContextOptionsBuilder optionsBuilder, CultureInfo culture = null) where TContext : DbContext - => (DbContextOptionsBuilder)UseUpperCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder); + => (DbContextOptionsBuilder)UseUpperCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder,culture); } }