SnakeCase,LowerCase, UpperCase Culture fix (#25)

Fixes #19
This commit is contained in:
Arda Terekeci
2020-05-04 13:32:09 +03:00
committed by Shay Rojansky
parent 2bacf92f66
commit 290cc33029
11 changed files with 108 additions and 33 deletions

View File

@@ -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));
}
}

View File

@@ -9,7 +9,6 @@ namespace EFCore.NamingConventions.Test
public class TestContext : DbContext
{
readonly Func<DbContextOptionsBuilder, DbContextOptionsBuilder> _useNamingConvention;
public TestContext(Func<DbContextOptionsBuilder, DbContextOptionsBuilder> useNamingConvention)
=> _useNamingConvention = useNamingConvention;

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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);
}
}

View File

@@ -1,5 +1,4 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Metadata.Conventions;

View File

@@ -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<NamingConventionsOptionsExtension>().NamingConvention;
var extension = _options.FindExtension<NamingConventionsOptionsExtension>();
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)
};

View File

@@ -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;
}

View File

@@ -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:

View File

@@ -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);
}
}

View File

@@ -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<NamingConventionsOptionsExtension>() ?? new NamingConventionsOptionsExtension())
.WithSnakeCaseNamingConvention();
.WithSnakeCaseNamingConvention(culture);
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
return optionsBuilder;
}
public static DbContextOptionsBuilder<TContext> UseSnakeCaseNamingConvention<TContext>([NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder)
public static DbContextOptionsBuilder<TContext> UseSnakeCaseNamingConvention<TContext>([NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder , CultureInfo culture = null)
where TContext : DbContext
=> (DbContextOptionsBuilder<TContext>)UseSnakeCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder);
=> (DbContextOptionsBuilder<TContext>)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<NamingConventionsOptionsExtension>() ?? new NamingConventionsOptionsExtension())
.WithLowerCaseNamingConvention();
.WithLowerCaseNamingConvention(culture);
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
return optionsBuilder;
}
public static DbContextOptionsBuilder<TContext> UseLowerCaseNamingConvention<TContext>([NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder)
public static DbContextOptionsBuilder<TContext> UseLowerCaseNamingConvention<TContext>([NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder, CultureInfo culture = null)
where TContext : DbContext
=> (DbContextOptionsBuilder<TContext>)UseLowerCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder);
=> (DbContextOptionsBuilder<TContext>)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<NamingConventionsOptionsExtension>() ?? new NamingConventionsOptionsExtension())
.WithUpperCaseNamingConvention();
.WithUpperCaseNamingConvention(culture);
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
return optionsBuilder;
}
public static DbContextOptionsBuilder<TContext> UseUpperCaseNamingConvention<TContext>([NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder)
public static DbContextOptionsBuilder<TContext> UseUpperCaseNamingConvention<TContext>([NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder, CultureInfo culture = null)
where TContext : DbContext
=> (DbContextOptionsBuilder<TContext>)UseUpperCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder);
=> (DbContextOptionsBuilder<TContext>)UseUpperCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder,culture);
}
}