From bc046ca65631d43ba417190852d79b1ae4d65a28 Mon Sep 17 00:00:00 2001 From: Fernando Contreras <60077230+fnandocontreras@users.noreply.github.com> Date: Mon, 18 Jan 2021 18:41:55 +0100 Subject: [PATCH] Adding support for lowercasing only the first character (#59) (#60) Closes #59 --- EFCore.NamingConventions.Test/RewriterTest.cs | 5 +++++ .../Internal/CamelCaseNameRewriter.cs | 14 ++++++++++++++ .../Internal/NamingConvention.cs | 1 + .../Internal/NamingConventionSetPlugin.cs | 1 + .../NamingConventionsOptionsExtension.cs | 9 +++++++++ .../NamingConventionsExtensions.cs | 19 +++++++++++++++++++ README.md | 1 + 7 files changed, 50 insertions(+) create mode 100644 EFCore.NamingConventions/Internal/CamelCaseNameRewriter.cs diff --git a/EFCore.NamingConventions.Test/RewriterTest.cs b/EFCore.NamingConventions.Test/RewriterTest.cs index 0447233..c2487af 100644 --- a/EFCore.NamingConventions.Test/RewriterTest.cs +++ b/EFCore.NamingConventions.Test/RewriterTest.cs @@ -21,6 +21,11 @@ namespace EFCore.NamingConventions.Test => Assert.Equal("fullname", new LowerCaseNameRewriter(CultureInfo.InvariantCulture).RewriteName("FullName")); + [Fact] + public void CamelCase() + => Assert.Equal("fullName", + new CamelCaseNameRewriter(CultureInfo.InvariantCulture).RewriteName("FullName")); + [Fact] public void UpperCase() => Assert.Equal("FULLNAME", diff --git a/EFCore.NamingConventions/Internal/CamelCaseNameRewriter.cs b/EFCore.NamingConventions/Internal/CamelCaseNameRewriter.cs new file mode 100644 index 0000000..e68b496 --- /dev/null +++ b/EFCore.NamingConventions/Internal/CamelCaseNameRewriter.cs @@ -0,0 +1,14 @@ +using System.Globalization; + +namespace EFCore.NamingConventions.Internal +{ + public class CamelCaseNameRewriter : INameRewriter + { + private readonly CultureInfo _culture; + + public CamelCaseNameRewriter(CultureInfo culture) => _culture = culture; + + public string RewriteName(string name) => + string.IsNullOrEmpty(name) ? name: char.ToLower(name[0], _culture) + name.Substring(1); + } +} diff --git a/EFCore.NamingConventions/Internal/NamingConvention.cs b/EFCore.NamingConventions/Internal/NamingConvention.cs index c8da151..305420d 100644 --- a/EFCore.NamingConventions/Internal/NamingConvention.cs +++ b/EFCore.NamingConventions/Internal/NamingConvention.cs @@ -5,6 +5,7 @@ namespace EFCore.NamingConventions.Internal None, SnakeCase, LowerCase, + CamelCase, UpperCase, UpperSnakeCase } diff --git a/EFCore.NamingConventions/Internal/NamingConventionSetPlugin.cs b/EFCore.NamingConventions/Internal/NamingConventionSetPlugin.cs index 2b1c990..335ff6f 100644 --- a/EFCore.NamingConventions/Internal/NamingConventionSetPlugin.cs +++ b/EFCore.NamingConventions/Internal/NamingConventionSetPlugin.cs @@ -26,6 +26,7 @@ namespace EFCore.NamingConventions.Internal { NamingConvention.SnakeCase => new SnakeCaseNameRewriter(culture ?? CultureInfo.InvariantCulture), NamingConvention.LowerCase => new LowerCaseNameRewriter(culture ?? CultureInfo.InvariantCulture), + NamingConvention.CamelCase => new CamelCaseNameRewriter(culture ?? CultureInfo.InvariantCulture), NamingConvention.UpperCase => new UpperCaseNameRewriter(culture ?? CultureInfo.InvariantCulture), NamingConvention.UpperSnakeCase => new UpperSnakeCaseNameRewriter(culture ?? CultureInfo.InvariantCulture), _ => throw new ArgumentOutOfRangeException("Unhandled enum value: " + namingStyle) diff --git a/EFCore.NamingConventions/Internal/NamingConventionsOptionsExtension.cs b/EFCore.NamingConventions/Internal/NamingConventionsOptionsExtension.cs index b514145..dfd9f9a 100644 --- a/EFCore.NamingConventions/Internal/NamingConventionsOptionsExtension.cs +++ b/EFCore.NamingConventions/Internal/NamingConventionsOptionsExtension.cs @@ -67,6 +67,14 @@ namespace EFCore.NamingConventions.Internal return clone; } + public virtual NamingConventionsOptionsExtension WithCamelCaseNamingConvention(CultureInfo culture = null) + { + var clone = Clone(); + clone._namingConvention = NamingConvention.CamelCase; + clone._culture = culture; + return clone; + } + public void Validate(IDbContextOptions options) {} public void ApplyServices(IServiceCollection services) @@ -97,6 +105,7 @@ namespace EFCore.NamingConventions.Internal NamingConvention.LowerCase => "using lower case naming", NamingConvention.UpperCase => "using upper case naming", NamingConvention.UpperSnakeCase => "using upper snake-case naming", + NamingConvention.CamelCase => "using camel-case naming", _ => throw new ArgumentOutOfRangeException("Unhandled enum value: " + Extension._namingConvention) }); diff --git a/EFCore.NamingConventions/NamingConventionsExtensions.cs b/EFCore.NamingConventions/NamingConventionsExtensions.cs index 027f2f3..fc94176 100644 --- a/EFCore.NamingConventions/NamingConventionsExtensions.cs +++ b/EFCore.NamingConventions/NamingConventionsExtensions.cs @@ -83,5 +83,24 @@ namespace Microsoft.EntityFrameworkCore [NotNull] this DbContextOptionsBuilder optionsBuilder, CultureInfo culture = null) where TContext : DbContext => (DbContextOptionsBuilder)UseUpperSnakeCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder, culture); + + public static DbContextOptionsBuilder UseCamelCaseNamingConvention( + [NotNull] this DbContextOptionsBuilder optionsBuilder, CultureInfo culture = null) + { + Check.NotNull(optionsBuilder, nameof(optionsBuilder)); + + var extension = (optionsBuilder.Options.FindExtension() + ?? new NamingConventionsOptionsExtension()) + .WithCamelCaseNamingConvention(culture); + + ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension); + + return optionsBuilder; + } + + public static DbContextOptionsBuilder UseCamelCaseNamingConvention( + [NotNull] this DbContextOptionsBuilder optionsBuilder, CultureInfo culture = null) + where TContext : DbContext + => (DbContextOptionsBuilder)UseCamelCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder, culture); } } diff --git a/README.md b/README.md index feb3eb4..8b1a46d 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ SELECT c.id, c.full_name * UseSnakeCaseNamingConvention: `FullName` becomes `full_name` * UseLowerCaseNamingConvention: `FullName` becomes `fullname` +* UseCamelCaseNamingConvention: `FullName` becomes `fullName` * UseUpperCaseNamingConvention: `FullName` becomes `FULLNAME` Have another naming convention in mind? Open an issue or even submit a PR - it's pretty easy to do!