mirror of
https://github.com/fergalmoran/EFCore.NamingConventions.git
synced 2025-12-22 01:28:13 +00:00
File-scoped namespaces
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -2,33 +2,32 @@ using System.Globalization;
|
||||
using EFCore.NamingConventions.Internal;
|
||||
using Xunit;
|
||||
|
||||
namespace EFCore.NamingConventions.Test
|
||||
namespace EFCore.NamingConventions.Test;
|
||||
|
||||
public class RewriterTest
|
||||
{
|
||||
public class RewriterTest
|
||||
{
|
||||
[Fact]
|
||||
public void SnakeCase()
|
||||
=> Assert.Equal("full_name",
|
||||
new SnakeCaseNameRewriter(CultureInfo.InvariantCulture).RewriteName("FullName"));
|
||||
[Fact]
|
||||
public void SnakeCase()
|
||||
=> Assert.Equal("full_name",
|
||||
new SnakeCaseNameRewriter(CultureInfo.InvariantCulture).RewriteName("FullName"));
|
||||
|
||||
[Fact]
|
||||
public void UpperSnakeCase()
|
||||
=> Assert.Equal("FULL_NAME",
|
||||
new UpperSnakeCaseNameRewriter(CultureInfo.InvariantCulture).RewriteName("FullName"));
|
||||
[Fact]
|
||||
public void UpperSnakeCase()
|
||||
=> Assert.Equal("FULL_NAME",
|
||||
new UpperSnakeCaseNameRewriter(CultureInfo.InvariantCulture).RewriteName("FullName"));
|
||||
|
||||
[Fact]
|
||||
public void LowerCase()
|
||||
=> Assert.Equal("fullname",
|
||||
new LowerCaseNameRewriter(CultureInfo.InvariantCulture).RewriteName("FullName"));
|
||||
[Fact]
|
||||
public void LowerCase()
|
||||
=> 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 CamelCase()
|
||||
=> Assert.Equal("fullName",
|
||||
new CamelCaseNameRewriter(CultureInfo.InvariantCulture).RewriteName("FullName"));
|
||||
|
||||
[Fact]
|
||||
public void UpperCase()
|
||||
=> Assert.Equal("FULLNAME",
|
||||
new UpperCaseNameRewriter(CultureInfo.InvariantCulture).RewriteName("FullName"));
|
||||
}
|
||||
}
|
||||
[Fact]
|
||||
public void UpperCase()
|
||||
=> Assert.Equal("FULLNAME",
|
||||
new UpperCaseNameRewriter(CultureInfo.InvariantCulture).RewriteName("FullName"));
|
||||
}
|
||||
@@ -7,24 +7,23 @@ using Microsoft.EntityFrameworkCore.Sqlite.Diagnostics.Internal;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Microsoft.EntityFrameworkCore.TestUtilities
|
||||
namespace Microsoft.EntityFrameworkCore.TestUtilities;
|
||||
|
||||
public class SqliteTestHelpers : TestHelpers
|
||||
{
|
||||
public class SqliteTestHelpers : TestHelpers
|
||||
protected SqliteTestHelpers()
|
||||
{
|
||||
protected SqliteTestHelpers()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static SqliteTestHelpers Instance { get; } = new();
|
||||
public static SqliteTestHelpers Instance { get; } = new();
|
||||
|
||||
public override IServiceCollection AddProviderServices(IServiceCollection services)
|
||||
=> services.AddEntityFrameworkSqlite();
|
||||
public override IServiceCollection AddProviderServices(IServiceCollection services)
|
||||
=> services.AddEntityFrameworkSqlite();
|
||||
|
||||
public override void UseProviderOptions(DbContextOptionsBuilder optionsBuilder)
|
||||
=> optionsBuilder.UseSqlite(new SqliteConnection("Data Source=:memory:"));
|
||||
public override void UseProviderOptions(DbContextOptionsBuilder optionsBuilder)
|
||||
=> optionsBuilder.UseSqlite(new SqliteConnection("Data Source=:memory:"));
|
||||
|
||||
#pragma warning disable EF1001
|
||||
public override LoggingDefinitions LoggingDefinitions { get; } = new SqliteLoggingDefinitions();
|
||||
public override LoggingDefinitions LoggingDefinitions { get; } = new SqliteLoggingDefinitions();
|
||||
#pragma warning restore EF1001
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,105 +6,104 @@ using JetBrains.Annotations;
|
||||
using Microsoft.EntityFrameworkCore.Diagnostics;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Microsoft.EntityFrameworkCore
|
||||
namespace Microsoft.EntityFrameworkCore;
|
||||
|
||||
[DebuggerStepThrough]
|
||||
internal static class Check
|
||||
{
|
||||
[DebuggerStepThrough]
|
||||
internal static class Check
|
||||
[ContractAnnotation("value:null => halt")]
|
||||
public static T NotNull<T>([NoEnumeration] T value, [InvokerParameterName] [NotNull] string parameterName)
|
||||
{
|
||||
[ContractAnnotation("value:null => halt")]
|
||||
public static T NotNull<T>([NoEnumeration] T value, [InvokerParameterName] [NotNull] string parameterName)
|
||||
if (ReferenceEquals(value, null))
|
||||
{
|
||||
if (ReferenceEquals(value, null))
|
||||
{
|
||||
NotEmpty(parameterName, nameof(parameterName));
|
||||
NotEmpty(parameterName, nameof(parameterName));
|
||||
|
||||
throw new ArgumentNullException(parameterName);
|
||||
}
|
||||
|
||||
return value;
|
||||
throw new ArgumentNullException(parameterName);
|
||||
}
|
||||
|
||||
[ContractAnnotation("value:null => halt")]
|
||||
public static T NotNull<T>(
|
||||
[NoEnumeration] T value,
|
||||
[InvokerParameterName] [NotNull] string parameterName,
|
||||
[NotNull] string propertyName)
|
||||
{
|
||||
if (ReferenceEquals(value, null))
|
||||
{
|
||||
NotEmpty(parameterName, nameof(parameterName));
|
||||
NotEmpty(propertyName, nameof(propertyName));
|
||||
|
||||
throw new ArgumentException(CoreStrings.ArgumentPropertyNull(propertyName, parameterName));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
[ContractAnnotation("value:null => halt")]
|
||||
public static IReadOnlyList<T> NotEmpty<T>(IReadOnlyList<T> value, [InvokerParameterName] [NotNull] string parameterName)
|
||||
{
|
||||
NotNull(value, parameterName);
|
||||
|
||||
if (value.Count == 0)
|
||||
{
|
||||
NotEmpty(parameterName, nameof(parameterName));
|
||||
|
||||
throw new ArgumentException(AbstractionsStrings.CollectionArgumentIsEmpty(parameterName));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
[ContractAnnotation("value:null => halt")]
|
||||
public static string NotEmpty(string value, [InvokerParameterName] [NotNull] string parameterName)
|
||||
{
|
||||
Exception e = null;
|
||||
if (ReferenceEquals(value, null))
|
||||
{
|
||||
e = new ArgumentNullException(parameterName);
|
||||
}
|
||||
else if (value.Trim().Length == 0)
|
||||
{
|
||||
e = new ArgumentException(AbstractionsStrings.ArgumentIsEmpty(parameterName));
|
||||
}
|
||||
|
||||
if (e != null)
|
||||
{
|
||||
NotEmpty(parameterName, nameof(parameterName));
|
||||
|
||||
throw e;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static string NullButNotEmpty([CanBeNull] string value, [InvokerParameterName] [NotNull] string parameterName)
|
||||
{
|
||||
if (!ReferenceEquals(value, null)
|
||||
&& (value.Length == 0))
|
||||
{
|
||||
NotEmpty(parameterName, nameof(parameterName));
|
||||
|
||||
throw new ArgumentException(AbstractionsStrings.ArgumentIsEmpty(parameterName));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static IReadOnlyList<T> HasNoNulls<T>(IReadOnlyList<T> value, [InvokerParameterName] [NotNull] string parameterName)
|
||||
where T : class
|
||||
{
|
||||
NotNull(value, parameterName);
|
||||
|
||||
if (value.Any(e => e == null))
|
||||
{
|
||||
NotEmpty(parameterName, nameof(parameterName));
|
||||
|
||||
throw new ArgumentException(parameterName);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
[ContractAnnotation("value:null => halt")]
|
||||
public static T NotNull<T>(
|
||||
[NoEnumeration] T value,
|
||||
[InvokerParameterName] [NotNull] string parameterName,
|
||||
[NotNull] string propertyName)
|
||||
{
|
||||
if (ReferenceEquals(value, null))
|
||||
{
|
||||
NotEmpty(parameterName, nameof(parameterName));
|
||||
NotEmpty(propertyName, nameof(propertyName));
|
||||
|
||||
throw new ArgumentException(CoreStrings.ArgumentPropertyNull(propertyName, parameterName));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
[ContractAnnotation("value:null => halt")]
|
||||
public static IReadOnlyList<T> NotEmpty<T>(IReadOnlyList<T> value, [InvokerParameterName] [NotNull] string parameterName)
|
||||
{
|
||||
NotNull(value, parameterName);
|
||||
|
||||
if (value.Count == 0)
|
||||
{
|
||||
NotEmpty(parameterName, nameof(parameterName));
|
||||
|
||||
throw new ArgumentException(AbstractionsStrings.CollectionArgumentIsEmpty(parameterName));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
[ContractAnnotation("value:null => halt")]
|
||||
public static string NotEmpty(string value, [InvokerParameterName] [NotNull] string parameterName)
|
||||
{
|
||||
Exception e = null;
|
||||
if (ReferenceEquals(value, null))
|
||||
{
|
||||
e = new ArgumentNullException(parameterName);
|
||||
}
|
||||
else if (value.Trim().Length == 0)
|
||||
{
|
||||
e = new ArgumentException(AbstractionsStrings.ArgumentIsEmpty(parameterName));
|
||||
}
|
||||
|
||||
if (e != null)
|
||||
{
|
||||
NotEmpty(parameterName, nameof(parameterName));
|
||||
|
||||
throw e;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static string NullButNotEmpty([CanBeNull] string value, [InvokerParameterName] [NotNull] string parameterName)
|
||||
{
|
||||
if (!ReferenceEquals(value, null)
|
||||
&& (value.Length == 0))
|
||||
{
|
||||
NotEmpty(parameterName, nameof(parameterName));
|
||||
|
||||
throw new ArgumentException(AbstractionsStrings.ArgumentIsEmpty(parameterName));
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static IReadOnlyList<T> HasNoNulls<T>(IReadOnlyList<T> value, [InvokerParameterName] [NotNull] string parameterName)
|
||||
where T : class
|
||||
{
|
||||
NotNull(value, parameterName);
|
||||
|
||||
if (value.Any(e => e == null))
|
||||
{
|
||||
NotEmpty(parameterName, nameof(parameterName));
|
||||
|
||||
throw new ArgumentException(parameterName);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -1,108 +1,107 @@
|
||||
using System;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace JetBrains.Annotations
|
||||
namespace JetBrains.Annotations;
|
||||
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Method | AttributeTargets.Parameter |
|
||||
AttributeTargets.Property | AttributeTargets.Delegate |
|
||||
AttributeTargets.Field)]
|
||||
internal sealed class NotNullAttribute : Attribute
|
||||
{
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Method | AttributeTargets.Parameter |
|
||||
AttributeTargets.Property | AttributeTargets.Delegate |
|
||||
AttributeTargets.Field)]
|
||||
internal sealed class NotNullAttribute : Attribute
|
||||
}
|
||||
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Method | AttributeTargets.Parameter |
|
||||
AttributeTargets.Property | AttributeTargets.Delegate |
|
||||
AttributeTargets.Field)]
|
||||
internal sealed class CanBeNullAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
internal sealed class InvokerParameterNameAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
internal sealed class NoEnumerationAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||
internal sealed class ContractAnnotationAttribute : Attribute
|
||||
{
|
||||
public string Contract { get; }
|
||||
|
||||
public bool ForceFullStates { get; }
|
||||
|
||||
public ContractAnnotationAttribute([NotNull] string contract)
|
||||
: this(contract, false)
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(
|
||||
AttributeTargets.Method | AttributeTargets.Parameter |
|
||||
AttributeTargets.Property | AttributeTargets.Delegate |
|
||||
AttributeTargets.Field)]
|
||||
internal sealed class CanBeNullAttribute : Attribute
|
||||
public ContractAnnotationAttribute([NotNull] string contract, bool forceFullStates)
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
internal sealed class InvokerParameterNameAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Parameter)]
|
||||
internal sealed class NoEnumerationAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
|
||||
internal sealed class ContractAnnotationAttribute : Attribute
|
||||
{
|
||||
public string Contract { get; }
|
||||
|
||||
public bool ForceFullStates { get; }
|
||||
|
||||
public ContractAnnotationAttribute([NotNull] string contract)
|
||||
: this(contract, false)
|
||||
{
|
||||
}
|
||||
|
||||
public ContractAnnotationAttribute([NotNull] string contract, bool forceFullStates)
|
||||
{
|
||||
Contract = contract;
|
||||
ForceFullStates = forceFullStates;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.All)]
|
||||
internal sealed class UsedImplicitlyAttribute : Attribute
|
||||
{
|
||||
public UsedImplicitlyAttribute()
|
||||
: this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default)
|
||||
{
|
||||
}
|
||||
|
||||
public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags)
|
||||
: this(useKindFlags, ImplicitUseTargetFlags.Default)
|
||||
{
|
||||
}
|
||||
|
||||
public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags)
|
||||
: this(ImplicitUseKindFlags.Default, targetFlags)
|
||||
{
|
||||
}
|
||||
|
||||
public UsedImplicitlyAttribute(
|
||||
ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
|
||||
{
|
||||
UseKindFlags = useKindFlags;
|
||||
TargetFlags = targetFlags;
|
||||
}
|
||||
|
||||
public ImplicitUseKindFlags UseKindFlags { get; }
|
||||
public ImplicitUseTargetFlags TargetFlags { get; }
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Delegate)]
|
||||
internal sealed class StringFormatMethodAttribute : Attribute
|
||||
{
|
||||
public StringFormatMethodAttribute([NotNull] string formatParameterName)
|
||||
=> FormatParameterName = formatParameterName;
|
||||
|
||||
[NotNull]
|
||||
public string FormatParameterName { get; }
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum ImplicitUseKindFlags
|
||||
{
|
||||
Default = Access | Assign | InstantiatedWithFixedConstructorSignature,
|
||||
Access = 1,
|
||||
Assign = 2,
|
||||
InstantiatedWithFixedConstructorSignature = 4,
|
||||
InstantiatedNoFixedConstructorSignature = 8
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum ImplicitUseTargetFlags
|
||||
{
|
||||
Default = Itself,
|
||||
Itself = 1,
|
||||
Members = 2,
|
||||
WithMembers = Itself | Members
|
||||
Contract = contract;
|
||||
ForceFullStates = forceFullStates;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.All)]
|
||||
internal sealed class UsedImplicitlyAttribute : Attribute
|
||||
{
|
||||
public UsedImplicitlyAttribute()
|
||||
: this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default)
|
||||
{
|
||||
}
|
||||
|
||||
public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags)
|
||||
: this(useKindFlags, ImplicitUseTargetFlags.Default)
|
||||
{
|
||||
}
|
||||
|
||||
public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags)
|
||||
: this(ImplicitUseKindFlags.Default, targetFlags)
|
||||
{
|
||||
}
|
||||
|
||||
public UsedImplicitlyAttribute(
|
||||
ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
|
||||
{
|
||||
UseKindFlags = useKindFlags;
|
||||
TargetFlags = targetFlags;
|
||||
}
|
||||
|
||||
public ImplicitUseKindFlags UseKindFlags { get; }
|
||||
public ImplicitUseTargetFlags TargetFlags { get; }
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Delegate)]
|
||||
internal sealed class StringFormatMethodAttribute : Attribute
|
||||
{
|
||||
public StringFormatMethodAttribute([NotNull] string formatParameterName)
|
||||
=> FormatParameterName = formatParameterName;
|
||||
|
||||
[NotNull]
|
||||
public string FormatParameterName { get; }
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum ImplicitUseKindFlags
|
||||
{
|
||||
Default = Access | Assign | InstantiatedWithFixedConstructorSignature,
|
||||
Access = 1,
|
||||
Assign = 2,
|
||||
InstantiatedWithFixedConstructorSignature = 4,
|
||||
InstantiatedNoFixedConstructorSignature = 8
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum ImplicitUseTargetFlags
|
||||
{
|
||||
Default = Itself,
|
||||
Itself = 1,
|
||||
Members = 2,
|
||||
WithMembers = Itself | Members
|
||||
}
|
||||
@@ -1,14 +1,13 @@
|
||||
using System.Globalization;
|
||||
|
||||
namespace EFCore.NamingConventions.Internal
|
||||
namespace EFCore.NamingConventions.Internal;
|
||||
|
||||
public class CamelCaseNameRewriter : INameRewriter
|
||||
{
|
||||
public class CamelCaseNameRewriter : INameRewriter
|
||||
{
|
||||
private readonly CultureInfo _culture;
|
||||
private readonly CultureInfo _culture;
|
||||
|
||||
public CamelCaseNameRewriter(CultureInfo culture) => _culture = culture;
|
||||
public CamelCaseNameRewriter(CultureInfo culture) => _culture = culture;
|
||||
|
||||
public string RewriteName(string name) =>
|
||||
string.IsNullOrEmpty(name) ? name: char.ToLower(name[0], _culture) + name.Substring(1);
|
||||
}
|
||||
}
|
||||
public string RewriteName(string name) =>
|
||||
string.IsNullOrEmpty(name) ? name: char.ToLower(name[0], _culture) + name.Substring(1);
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
namespace EFCore.NamingConventions.Internal
|
||||
namespace EFCore.NamingConventions.Internal;
|
||||
|
||||
public interface INameRewriter
|
||||
{
|
||||
public interface INameRewriter
|
||||
{
|
||||
string RewriteName(string name);
|
||||
}
|
||||
}
|
||||
string RewriteName(string name);
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
using System.Globalization;
|
||||
|
||||
namespace EFCore.NamingConventions.Internal
|
||||
{
|
||||
public class LowerCaseNameRewriter : INameRewriter
|
||||
{
|
||||
private readonly CultureInfo _culture;
|
||||
namespace EFCore.NamingConventions.Internal;
|
||||
|
||||
public LowerCaseNameRewriter(CultureInfo culture) => _culture = culture;
|
||||
public string RewriteName(string name) => name.ToLower(_culture);
|
||||
}
|
||||
}
|
||||
public class LowerCaseNameRewriter : INameRewriter
|
||||
{
|
||||
private readonly CultureInfo _culture;
|
||||
|
||||
public LowerCaseNameRewriter(CultureInfo culture) => _culture = culture;
|
||||
public string RewriteName(string name) => name.ToLower(_culture);
|
||||
}
|
||||
@@ -5,278 +5,277 @@ using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Conventions;
|
||||
|
||||
namespace EFCore.NamingConventions.Internal
|
||||
namespace EFCore.NamingConventions.Internal;
|
||||
|
||||
public class NameRewritingConvention :
|
||||
IEntityTypeAddedConvention,
|
||||
IEntityTypeAnnotationChangedConvention,
|
||||
IPropertyAddedConvention,
|
||||
IForeignKeyOwnershipChangedConvention,
|
||||
IKeyAddedConvention,
|
||||
IForeignKeyAddedConvention,
|
||||
IIndexAddedConvention,
|
||||
IEntityTypeBaseTypeChangedConvention,
|
||||
IModelFinalizingConvention
|
||||
{
|
||||
public class NameRewritingConvention :
|
||||
IEntityTypeAddedConvention,
|
||||
IEntityTypeAnnotationChangedConvention,
|
||||
IPropertyAddedConvention,
|
||||
IForeignKeyOwnershipChangedConvention,
|
||||
IKeyAddedConvention,
|
||||
IForeignKeyAddedConvention,
|
||||
IIndexAddedConvention,
|
||||
IEntityTypeBaseTypeChangedConvention,
|
||||
IModelFinalizingConvention
|
||||
private static readonly StoreObjectType[] _storeObjectTypes
|
||||
= { StoreObjectType.Table, StoreObjectType.View, StoreObjectType.Function, StoreObjectType.SqlQuery };
|
||||
|
||||
private readonly INameRewriter _namingNameRewriter;
|
||||
|
||||
public NameRewritingConvention(INameRewriter nameRewriter)
|
||||
=> _namingNameRewriter = nameRewriter;
|
||||
|
||||
public virtual void ProcessEntityTypeAdded(
|
||||
IConventionEntityTypeBuilder entityTypeBuilder,
|
||||
IConventionContext<IConventionEntityTypeBuilder> context)
|
||||
{
|
||||
private static readonly StoreObjectType[] _storeObjectTypes
|
||||
= { StoreObjectType.Table, StoreObjectType.View, StoreObjectType.Function, StoreObjectType.SqlQuery };
|
||||
var entityType = entityTypeBuilder.Metadata;
|
||||
|
||||
private readonly INameRewriter _namingNameRewriter;
|
||||
|
||||
public NameRewritingConvention(INameRewriter nameRewriter)
|
||||
=> _namingNameRewriter = nameRewriter;
|
||||
|
||||
public virtual void ProcessEntityTypeAdded(
|
||||
IConventionEntityTypeBuilder entityTypeBuilder,
|
||||
IConventionContext<IConventionEntityTypeBuilder> context)
|
||||
// Note that the base type is null when the entity type is first added - a base type only gets added later
|
||||
// (see ProcessEntityTypeBaseTypeChanged). But we still have this check for safety.
|
||||
if (entityType.BaseType is null)
|
||||
{
|
||||
var entityType = entityTypeBuilder.Metadata;
|
||||
entityTypeBuilder.ToTable(_namingNameRewriter.RewriteName(entityType.GetTableName()), entityType.GetSchema());
|
||||
|
||||
// Note that the base type is null when the entity type is first added - a base type only gets added later
|
||||
// (see ProcessEntityTypeBaseTypeChanged). But we still have this check for safety.
|
||||
if (entityType.BaseType is null)
|
||||
if (entityType.GetViewNameConfigurationSource() == ConfigurationSource.Convention)
|
||||
{
|
||||
entityTypeBuilder.ToTable(_namingNameRewriter.RewriteName(entityType.GetTableName()), entityType.GetSchema());
|
||||
|
||||
if (entityType.GetViewNameConfigurationSource() == ConfigurationSource.Convention)
|
||||
{
|
||||
entityTypeBuilder.ToView(_namingNameRewriter.RewriteName(entityType.GetViewName()), entityType.GetViewSchema());
|
||||
}
|
||||
entityTypeBuilder.ToView(_namingNameRewriter.RewriteName(entityType.GetViewName()), entityType.GetViewSchema());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessEntityTypeBaseTypeChanged(
|
||||
IConventionEntityTypeBuilder entityTypeBuilder,
|
||||
IConventionEntityType newBaseType,
|
||||
IConventionEntityType oldBaseType,
|
||||
IConventionContext<IConventionEntityType> context)
|
||||
public void ProcessEntityTypeBaseTypeChanged(
|
||||
IConventionEntityTypeBuilder entityTypeBuilder,
|
||||
IConventionEntityType newBaseType,
|
||||
IConventionEntityType oldBaseType,
|
||||
IConventionContext<IConventionEntityType> context)
|
||||
{
|
||||
var entityType = entityTypeBuilder.Metadata;
|
||||
|
||||
if (newBaseType is null)
|
||||
{
|
||||
var entityType = entityTypeBuilder.Metadata;
|
||||
// The entity is getting removed from a hierarchy. Set the (rewritten) TableName.
|
||||
entityTypeBuilder.ToTable(_namingNameRewriter.RewriteName(entityType.GetTableName()), entityType.GetSchema());
|
||||
}
|
||||
else
|
||||
{
|
||||
// The entity is getting a new base type (e.g. joining a hierarchy).
|
||||
// If this is TPH, we remove the previously rewritten TableName (and non-rewritten Schema) which we set when the
|
||||
// entity type was first added to the model (see ProcessEntityTypeAdded).
|
||||
// If this is TPT, TableName and Schema are set explicitly, so the following will be ignored.
|
||||
entityTypeBuilder.HasNoAnnotation(RelationalAnnotationNames.TableName);
|
||||
entityTypeBuilder.HasNoAnnotation(RelationalAnnotationNames.Schema);
|
||||
}
|
||||
}
|
||||
|
||||
if (newBaseType is null)
|
||||
public virtual void ProcessPropertyAdded(
|
||||
IConventionPropertyBuilder propertyBuilder,
|
||||
IConventionContext<IConventionPropertyBuilder> context)
|
||||
=> RewriteColumnName(propertyBuilder);
|
||||
|
||||
public void ProcessForeignKeyOwnershipChanged(IConventionForeignKeyBuilder relationshipBuilder, IConventionContext<bool?> context)
|
||||
{
|
||||
var foreignKey = relationshipBuilder.Metadata;
|
||||
var ownedEntityType = foreignKey.DeclaringEntityType;
|
||||
|
||||
// An entity type is becoming owned - this is a bit complicated.
|
||||
// Unless it's a collection navigation, or the owned entity table name was explicitly set by the user, this triggers table
|
||||
// splitting, which means we need to undo rewriting which we've done previously.
|
||||
if (foreignKey.IsOwnership
|
||||
&& !foreignKey.GetNavigation(false).IsCollection
|
||||
&& ownedEntityType.GetTableNameConfigurationSource() != ConfigurationSource.Explicit)
|
||||
{
|
||||
// Reset the table name which we've set when the entity type was added.
|
||||
// If table splitting was configured by explicitly setting the table name, the following
|
||||
// does nothing.
|
||||
ownedEntityType.Builder.HasNoAnnotation(RelationalAnnotationNames.TableName);
|
||||
ownedEntityType.Builder.HasNoAnnotation(RelationalAnnotationNames.Schema);
|
||||
|
||||
ownedEntityType.FindPrimaryKey()?.Builder.HasNoAnnotation(RelationalAnnotationNames.Name);
|
||||
|
||||
// We've previously set rewritten column names when the entity was originally added (before becoming owned).
|
||||
// These need to be rewritten again to include the owner prefix.
|
||||
foreach (var property in ownedEntityType.GetProperties())
|
||||
{
|
||||
// The entity is getting removed from a hierarchy. Set the (rewritten) TableName.
|
||||
entityTypeBuilder.ToTable(_namingNameRewriter.RewriteName(entityType.GetTableName()), entityType.GetSchema());
|
||||
RewriteColumnName(property.Builder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessEntityTypeAnnotationChanged(
|
||||
IConventionEntityTypeBuilder entityTypeBuilder,
|
||||
string name,
|
||||
IConventionAnnotation annotation,
|
||||
IConventionAnnotation oldAnnotation,
|
||||
IConventionContext<IConventionAnnotation> context)
|
||||
{
|
||||
var entityType = entityTypeBuilder.Metadata;
|
||||
|
||||
// If the View/SqlQuery/Function name is being set on the entity type, and its table name is set by convention, then we assume
|
||||
// we're the one who set the table name back when the entity type was originally added. We now undo this as the entity type
|
||||
// should only be mapped to the View/SqlQuery/Function.
|
||||
if (name is RelationalAnnotationNames.ViewName or RelationalAnnotationNames.SqlQuery or RelationalAnnotationNames.FunctionName
|
||||
&& annotation.Value is not null
|
||||
&& entityType.GetTableNameConfigurationSource() == ConfigurationSource.Convention)
|
||||
{
|
||||
entityType.SetTableName(null);
|
||||
}
|
||||
|
||||
if (name != RelationalAnnotationNames.TableName
|
||||
|| StoreObjectIdentifier.Create(entityType, StoreObjectType.Table) is not StoreObjectIdentifier tableIdentifier)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// The table's name is changing - rewrite keys, index names
|
||||
|
||||
if (entityType.FindPrimaryKey() is IConventionKey primaryKey)
|
||||
{
|
||||
// We need to rewrite the PK name.
|
||||
// However, this isn't yet supported with TPT, see https://github.com/dotnet/efcore/issues/23444.
|
||||
// So we need to check if the entity is within a TPT hierarchy, or is an owned entity within a TPT hierarchy.
|
||||
|
||||
var rootType = entityType.GetRootType();
|
||||
var isTPT = rootType.GetDerivedTypes().FirstOrDefault() is { } derivedType
|
||||
&& derivedType.GetTableName() != rootType.GetTableName();
|
||||
|
||||
if (entityType.FindRowInternalForeignKeys(tableIdentifier).FirstOrDefault() is null && !isTPT)
|
||||
{
|
||||
primaryKey.Builder.HasName(_namingNameRewriter.RewriteName(primaryKey.GetDefaultName()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// The entity is getting a new base type (e.g. joining a hierarchy).
|
||||
// If this is TPH, we remove the previously rewritten TableName (and non-rewritten Schema) which we set when the
|
||||
// entity type was first added to the model (see ProcessEntityTypeAdded).
|
||||
// If this is TPT, TableName and Schema are set explicitly, so the following will be ignored.
|
||||
entityTypeBuilder.HasNoAnnotation(RelationalAnnotationNames.TableName);
|
||||
entityTypeBuilder.HasNoAnnotation(RelationalAnnotationNames.Schema);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ProcessPropertyAdded(
|
||||
IConventionPropertyBuilder propertyBuilder,
|
||||
IConventionContext<IConventionPropertyBuilder> context)
|
||||
=> RewriteColumnName(propertyBuilder);
|
||||
|
||||
public void ProcessForeignKeyOwnershipChanged(IConventionForeignKeyBuilder relationshipBuilder, IConventionContext<bool?> context)
|
||||
{
|
||||
var foreignKey = relationshipBuilder.Metadata;
|
||||
var ownedEntityType = foreignKey.DeclaringEntityType;
|
||||
|
||||
// An entity type is becoming owned - this is a bit complicated.
|
||||
// Unless it's a collection navigation, or the owned entity table name was explicitly set by the user, this triggers table
|
||||
// splitting, which means we need to undo rewriting which we've done previously.
|
||||
if (foreignKey.IsOwnership
|
||||
&& !foreignKey.GetNavigation(false).IsCollection
|
||||
&& ownedEntityType.GetTableNameConfigurationSource() != ConfigurationSource.Explicit)
|
||||
{
|
||||
// Reset the table name which we've set when the entity type was added.
|
||||
// If table splitting was configured by explicitly setting the table name, the following
|
||||
// does nothing.
|
||||
ownedEntityType.Builder.HasNoAnnotation(RelationalAnnotationNames.TableName);
|
||||
ownedEntityType.Builder.HasNoAnnotation(RelationalAnnotationNames.Schema);
|
||||
|
||||
ownedEntityType.FindPrimaryKey()?.Builder.HasNoAnnotation(RelationalAnnotationNames.Name);
|
||||
|
||||
// We've previously set rewritten column names when the entity was originally added (before becoming owned).
|
||||
// These need to be rewritten again to include the owner prefix.
|
||||
foreach (var property in ownedEntityType.GetProperties())
|
||||
// This hierarchy is being transformed into TPT via the explicit setting of the table name.
|
||||
// We not only have to reset our own key name, but also the parents'. Otherwise, the parent's key name
|
||||
// is used as the child's (see RelationalKeyExtensions.GetName), and we get a "duplicate key name in database" error
|
||||
// since both parent and child have the same key name;
|
||||
foreach (var type in entityType.GetRootType().GetDerivedTypesInclusive())
|
||||
{
|
||||
RewriteColumnName(property.Builder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessEntityTypeAnnotationChanged(
|
||||
IConventionEntityTypeBuilder entityTypeBuilder,
|
||||
string name,
|
||||
IConventionAnnotation annotation,
|
||||
IConventionAnnotation oldAnnotation,
|
||||
IConventionContext<IConventionAnnotation> context)
|
||||
{
|
||||
var entityType = entityTypeBuilder.Metadata;
|
||||
|
||||
// If the View/SqlQuery/Function name is being set on the entity type, and its table name is set by convention, then we assume
|
||||
// we're the one who set the table name back when the entity type was originally added. We now undo this as the entity type
|
||||
// should only be mapped to the View/SqlQuery/Function.
|
||||
if (name is RelationalAnnotationNames.ViewName or RelationalAnnotationNames.SqlQuery or RelationalAnnotationNames.FunctionName
|
||||
&& annotation.Value is not null
|
||||
&& entityType.GetTableNameConfigurationSource() == ConfigurationSource.Convention)
|
||||
{
|
||||
entityType.SetTableName(null);
|
||||
}
|
||||
|
||||
if (name != RelationalAnnotationNames.TableName
|
||||
|| StoreObjectIdentifier.Create(entityType, StoreObjectType.Table) is not StoreObjectIdentifier tableIdentifier)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// The table's name is changing - rewrite keys, index names
|
||||
|
||||
if (entityType.FindPrimaryKey() is IConventionKey primaryKey)
|
||||
{
|
||||
// We need to rewrite the PK name.
|
||||
// However, this isn't yet supported with TPT, see https://github.com/dotnet/efcore/issues/23444.
|
||||
// So we need to check if the entity is within a TPT hierarchy, or is an owned entity within a TPT hierarchy.
|
||||
|
||||
var rootType = entityType.GetRootType();
|
||||
var isTPT = rootType.GetDerivedTypes().FirstOrDefault() is { } derivedType
|
||||
&& derivedType.GetTableName() != rootType.GetTableName();
|
||||
|
||||
if (entityType.FindRowInternalForeignKeys(tableIdentifier).FirstOrDefault() is null && !isTPT)
|
||||
{
|
||||
primaryKey.Builder.HasName(_namingNameRewriter.RewriteName(primaryKey.GetDefaultName()));
|
||||
}
|
||||
else
|
||||
{
|
||||
// This hierarchy is being transformed into TPT via the explicit setting of the table name.
|
||||
// We not only have to reset our own key name, but also the parents'. Otherwise, the parent's key name
|
||||
// is used as the child's (see RelationalKeyExtensions.GetName), and we get a "duplicate key name in database" error
|
||||
// since both parent and child have the same key name;
|
||||
foreach (var type in entityType.GetRootType().GetDerivedTypesInclusive())
|
||||
if (type.FindPrimaryKey() is IConventionKey pk)
|
||||
{
|
||||
if (type.FindPrimaryKey() is IConventionKey pk)
|
||||
{
|
||||
pk.Builder.HasNoAnnotation(RelationalAnnotationNames.Name);
|
||||
}
|
||||
pk.Builder.HasNoAnnotation(RelationalAnnotationNames.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var foreignKey in entityType.GetForeignKeys())
|
||||
{
|
||||
foreignKey.Builder.HasConstraintName(_namingNameRewriter.RewriteName(foreignKey.GetDefaultName()));
|
||||
}
|
||||
|
||||
foreach (var index in entityType.GetIndexes())
|
||||
{
|
||||
index.Builder.HasDatabaseName(_namingNameRewriter.RewriteName(index.GetDefaultDatabaseName()));
|
||||
}
|
||||
|
||||
if (annotation?.Value is not null
|
||||
&& entityType.FindOwnership() is IConventionForeignKey ownership
|
||||
&& (string)annotation.Value != ownership.PrincipalEntityType.GetTableName())
|
||||
{
|
||||
// An owned entity's table is being set explicitly - this is the trigger to undo table splitting (which is the default).
|
||||
|
||||
// When the entity became owned, we prefixed all of its properties - we must now undo that.
|
||||
foreach (var property in entityType.GetProperties()
|
||||
.Except(entityType.FindPrimaryKey().Properties)
|
||||
.Where(p => p.Builder.CanSetColumnName(null)))
|
||||
{
|
||||
RewriteColumnName(property.Builder);
|
||||
}
|
||||
|
||||
// We previously rewrote the owned entity's primary key name, when the owned entity was still in table splitting.
|
||||
// Now that its getting its own table, rewrite the primary key constraint name again.
|
||||
if (entityType.FindPrimaryKey() is IConventionKey key)
|
||||
{
|
||||
key.Builder.HasName(_namingNameRewriter.RewriteName(key.GetDefaultName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessForeignKeyAdded(
|
||||
IConventionForeignKeyBuilder relationshipBuilder,
|
||||
IConventionContext<IConventionForeignKeyBuilder> context)
|
||||
=> relationshipBuilder.HasConstraintName(_namingNameRewriter.RewriteName(relationshipBuilder.Metadata.GetDefaultName()));
|
||||
|
||||
public void ProcessKeyAdded(IConventionKeyBuilder keyBuilder, IConventionContext<IConventionKeyBuilder> context)
|
||||
=> keyBuilder.HasName(_namingNameRewriter.RewriteName(keyBuilder.Metadata.GetName()));
|
||||
|
||||
public void ProcessIndexAdded(
|
||||
IConventionIndexBuilder indexBuilder,
|
||||
IConventionContext<IConventionIndexBuilder> context)
|
||||
=> indexBuilder.HasDatabaseName(_namingNameRewriter.RewriteName(indexBuilder.Metadata.GetDefaultDatabaseName()));
|
||||
|
||||
/// <summary>
|
||||
/// EF Core's <see cref="SharedTableConvention" /> runs at model finalization time, and adds entity type prefixes to
|
||||
/// clashing columns. These prefixes also needs to be rewritten by us, so we run after that convention to do that.
|
||||
/// </summary>
|
||||
public void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext<IConventionModelBuilder> context)
|
||||
foreach (var foreignKey in entityType.GetForeignKeys())
|
||||
{
|
||||
foreach (var entityType in modelBuilder.Metadata.GetEntityTypes())
|
||||
foreignKey.Builder.HasConstraintName(_namingNameRewriter.RewriteName(foreignKey.GetDefaultName()));
|
||||
}
|
||||
|
||||
foreach (var index in entityType.GetIndexes())
|
||||
{
|
||||
index.Builder.HasDatabaseName(_namingNameRewriter.RewriteName(index.GetDefaultDatabaseName()));
|
||||
}
|
||||
|
||||
if (annotation?.Value is not null
|
||||
&& entityType.FindOwnership() is IConventionForeignKey ownership
|
||||
&& (string)annotation.Value != ownership.PrincipalEntityType.GetTableName())
|
||||
{
|
||||
// An owned entity's table is being set explicitly - this is the trigger to undo table splitting (which is the default).
|
||||
|
||||
// When the entity became owned, we prefixed all of its properties - we must now undo that.
|
||||
foreach (var property in entityType.GetProperties()
|
||||
.Except(entityType.FindPrimaryKey().Properties)
|
||||
.Where(p => p.Builder.CanSetColumnName(null)))
|
||||
{
|
||||
foreach (var property in entityType.GetProperties())
|
||||
RewriteColumnName(property.Builder);
|
||||
}
|
||||
|
||||
// We previously rewrote the owned entity's primary key name, when the owned entity was still in table splitting.
|
||||
// Now that its getting its own table, rewrite the primary key constraint name again.
|
||||
if (entityType.FindPrimaryKey() is IConventionKey key)
|
||||
{
|
||||
key.Builder.HasName(_namingNameRewriter.RewriteName(key.GetDefaultName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessForeignKeyAdded(
|
||||
IConventionForeignKeyBuilder relationshipBuilder,
|
||||
IConventionContext<IConventionForeignKeyBuilder> context)
|
||||
=> relationshipBuilder.HasConstraintName(_namingNameRewriter.RewriteName(relationshipBuilder.Metadata.GetDefaultName()));
|
||||
|
||||
public void ProcessKeyAdded(IConventionKeyBuilder keyBuilder, IConventionContext<IConventionKeyBuilder> context)
|
||||
=> keyBuilder.HasName(_namingNameRewriter.RewriteName(keyBuilder.Metadata.GetName()));
|
||||
|
||||
public void ProcessIndexAdded(
|
||||
IConventionIndexBuilder indexBuilder,
|
||||
IConventionContext<IConventionIndexBuilder> context)
|
||||
=> indexBuilder.HasDatabaseName(_namingNameRewriter.RewriteName(indexBuilder.Metadata.GetDefaultDatabaseName()));
|
||||
|
||||
/// <summary>
|
||||
/// EF Core's <see cref="SharedTableConvention" /> runs at model finalization time, and adds entity type prefixes to
|
||||
/// clashing columns. These prefixes also needs to be rewritten by us, so we run after that convention to do that.
|
||||
/// </summary>
|
||||
public void ProcessModelFinalizing(IConventionModelBuilder modelBuilder, IConventionContext<IConventionModelBuilder> context)
|
||||
{
|
||||
foreach (var entityType in modelBuilder.Metadata.GetEntityTypes())
|
||||
{
|
||||
foreach (var property in entityType.GetProperties())
|
||||
{
|
||||
var columnName = property.GetColumnBaseName();
|
||||
if (columnName.StartsWith(entityType.ShortName() + '_', StringComparison.Ordinal))
|
||||
{
|
||||
var columnName = property.GetColumnBaseName();
|
||||
property.Builder.HasColumnName(
|
||||
_namingNameRewriter.RewriteName(entityType.ShortName()) + columnName.Substring(entityType.ShortName().Length));
|
||||
}
|
||||
|
||||
foreach (var storeObjectType in _storeObjectTypes)
|
||||
{
|
||||
var identifier = StoreObjectIdentifier.Create(entityType, storeObjectType);
|
||||
if (identifier is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (property.GetColumnNameConfigurationSource(identifier.Value) != ConfigurationSource.Convention)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
columnName = property.GetColumnName(identifier.Value);
|
||||
if (columnName.StartsWith(entityType.ShortName() + '_', StringComparison.Ordinal))
|
||||
{
|
||||
property.Builder.HasColumnName(
|
||||
_namingNameRewriter.RewriteName(entityType.ShortName()) + columnName.Substring(entityType.ShortName().Length));
|
||||
_namingNameRewriter.RewriteName(entityType.ShortName())
|
||||
+ columnName.Substring(entityType.ShortName().Length));
|
||||
}
|
||||
|
||||
foreach (var storeObjectType in _storeObjectTypes)
|
||||
{
|
||||
var identifier = StoreObjectIdentifier.Create(entityType, storeObjectType);
|
||||
if (identifier is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (property.GetColumnNameConfigurationSource(identifier.Value) != ConfigurationSource.Convention)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
columnName = property.GetColumnName(identifier.Value);
|
||||
if (columnName.StartsWith(entityType.ShortName() + '_', StringComparison.Ordinal))
|
||||
{
|
||||
property.Builder.HasColumnName(
|
||||
_namingNameRewriter.RewriteName(entityType.ShortName())
|
||||
+ columnName.Substring(entityType.ShortName().Length));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RewriteColumnName(IConventionPropertyBuilder propertyBuilder)
|
||||
{
|
||||
var property = propertyBuilder.Metadata;
|
||||
var entityType = property.DeclaringEntityType;
|
||||
|
||||
// Remove any previous setting of the column name we may have done, so we can get the default recalculated below.
|
||||
property.Builder.HasNoAnnotation(RelationalAnnotationNames.ColumnName);
|
||||
|
||||
// TODO: The following is a temporary hack. We should probably just always set the relational override below,
|
||||
// but https://github.com/dotnet/efcore/pull/23834
|
||||
var baseColumnName = StoreObjectIdentifier.Create(property.DeclaringEntityType, StoreObjectType.Table) is { } tableIdentifier
|
||||
? property.GetDefaultColumnName(tableIdentifier)
|
||||
: property.GetDefaultColumnBaseName();
|
||||
propertyBuilder.HasColumnName(_namingNameRewriter.RewriteName(baseColumnName));
|
||||
|
||||
foreach (var storeObjectType in _storeObjectTypes)
|
||||
{
|
||||
var identifier = StoreObjectIdentifier.Create(entityType, storeObjectType);
|
||||
if (identifier is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (property.GetColumnNameConfigurationSource(identifier.Value) == ConfigurationSource.Convention)
|
||||
{
|
||||
propertyBuilder.HasColumnName(
|
||||
_namingNameRewriter.RewriteName(property.GetColumnName(identifier.Value)), identifier.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RewriteColumnName(IConventionPropertyBuilder propertyBuilder)
|
||||
{
|
||||
var property = propertyBuilder.Metadata;
|
||||
var entityType = property.DeclaringEntityType;
|
||||
|
||||
// Remove any previous setting of the column name we may have done, so we can get the default recalculated below.
|
||||
property.Builder.HasNoAnnotation(RelationalAnnotationNames.ColumnName);
|
||||
|
||||
// TODO: The following is a temporary hack. We should probably just always set the relational override below,
|
||||
// but https://github.com/dotnet/efcore/pull/23834
|
||||
var baseColumnName = StoreObjectIdentifier.Create(property.DeclaringEntityType, StoreObjectType.Table) is { } tableIdentifier
|
||||
? property.GetDefaultColumnName(tableIdentifier)
|
||||
: property.GetDefaultColumnBaseName();
|
||||
propertyBuilder.HasColumnName(_namingNameRewriter.RewriteName(baseColumnName));
|
||||
|
||||
foreach (var storeObjectType in _storeObjectTypes)
|
||||
{
|
||||
var identifier = StoreObjectIdentifier.Create(entityType, storeObjectType);
|
||||
if (identifier is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (property.GetColumnNameConfigurationSource(identifier.Value) == ConfigurationSource.Convention)
|
||||
{
|
||||
propertyBuilder.HasColumnName(
|
||||
_namingNameRewriter.RewriteName(property.GetColumnName(identifier.Value)), identifier.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
namespace EFCore.NamingConventions.Internal
|
||||
namespace EFCore.NamingConventions.Internal;
|
||||
|
||||
public enum NamingConvention
|
||||
{
|
||||
public enum NamingConvention
|
||||
{
|
||||
None,
|
||||
SnakeCase,
|
||||
LowerCase,
|
||||
CamelCase,
|
||||
UpperCase,
|
||||
UpperSnakeCase
|
||||
}
|
||||
None,
|
||||
SnakeCase,
|
||||
LowerCase,
|
||||
CamelCase,
|
||||
UpperCase,
|
||||
UpperSnakeCase
|
||||
}
|
||||
|
||||
@@ -5,44 +5,43 @@ using Microsoft.EntityFrameworkCore.Metadata.Conventions;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Conventions.Infrastructure;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace EFCore.NamingConventions.Internal
|
||||
namespace EFCore.NamingConventions.Internal;
|
||||
|
||||
public class NamingConventionSetPlugin : IConventionSetPlugin
|
||||
{
|
||||
public class NamingConventionSetPlugin : IConventionSetPlugin
|
||||
private readonly IDbContextOptions _options;
|
||||
public NamingConventionSetPlugin([NotNull] IDbContextOptions options) => _options = options;
|
||||
|
||||
public ConventionSet ModifyConventions(ConventionSet conventionSet)
|
||||
{
|
||||
private readonly IDbContextOptions _options;
|
||||
public NamingConventionSetPlugin([NotNull] IDbContextOptions options) => _options = options;
|
||||
|
||||
public ConventionSet ModifyConventions(ConventionSet conventionSet)
|
||||
var extension = _options.FindExtension<NamingConventionsOptionsExtension>();
|
||||
var namingStyle = extension.NamingConvention;
|
||||
var culture = extension.Culture;
|
||||
if (namingStyle == NamingConvention.None)
|
||||
{
|
||||
var extension = _options.FindExtension<NamingConventionsOptionsExtension>();
|
||||
var namingStyle = extension.NamingConvention;
|
||||
var culture = extension.Culture;
|
||||
if (namingStyle == NamingConvention.None)
|
||||
{
|
||||
return conventionSet;
|
||||
}
|
||||
|
||||
var convention = new NameRewritingConvention(namingStyle switch
|
||||
{
|
||||
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)
|
||||
});
|
||||
|
||||
conventionSet.EntityTypeAddedConventions.Add(convention);
|
||||
conventionSet.EntityTypeAnnotationChangedConventions.Add(convention);
|
||||
conventionSet.PropertyAddedConventions.Add(convention);
|
||||
conventionSet.ForeignKeyOwnershipChangedConventions.Add(convention);
|
||||
conventionSet.KeyAddedConventions.Add(convention);
|
||||
conventionSet.ForeignKeyAddedConventions.Add(convention);
|
||||
conventionSet.IndexAddedConventions.Add(convention);
|
||||
conventionSet.EntityTypeBaseTypeChangedConventions.Add(convention);
|
||||
conventionSet.ModelFinalizingConventions.Add(convention);
|
||||
|
||||
return conventionSet;
|
||||
}
|
||||
|
||||
var convention = new NameRewritingConvention(namingStyle switch
|
||||
{
|
||||
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)
|
||||
});
|
||||
|
||||
conventionSet.EntityTypeAddedConventions.Add(convention);
|
||||
conventionSet.EntityTypeAnnotationChangedConventions.Add(convention);
|
||||
conventionSet.PropertyAddedConventions.Add(convention);
|
||||
conventionSet.ForeignKeyOwnershipChangedConventions.Add(convention);
|
||||
conventionSet.KeyAddedConventions.Add(convention);
|
||||
conventionSet.ForeignKeyAddedConventions.Add(convention);
|
||||
conventionSet.IndexAddedConventions.Add(convention);
|
||||
conventionSet.EntityTypeBaseTypeChangedConventions.Add(convention);
|
||||
conventionSet.ModelFinalizingConventions.Add(convention);
|
||||
|
||||
return conventionSet;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,144 +6,143 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace EFCore.NamingConventions.Internal
|
||||
namespace EFCore.NamingConventions.Internal;
|
||||
|
||||
public class NamingConventionsOptionsExtension : IDbContextOptionsExtension
|
||||
{
|
||||
public class NamingConventionsOptionsExtension : IDbContextOptionsExtension
|
||||
private DbContextOptionsExtensionInfo _info;
|
||||
private NamingConvention _namingConvention;
|
||||
private CultureInfo _culture;
|
||||
|
||||
public NamingConventionsOptionsExtension() {}
|
||||
protected NamingConventionsOptionsExtension([NotNull] NamingConventionsOptionsExtension copyFrom)
|
||||
{
|
||||
private DbContextOptionsExtensionInfo _info;
|
||||
private NamingConvention _namingConvention;
|
||||
private CultureInfo _culture;
|
||||
_namingConvention = copyFrom._namingConvention;
|
||||
_culture = copyFrom._culture;
|
||||
}
|
||||
|
||||
public NamingConventionsOptionsExtension() {}
|
||||
protected NamingConventionsOptionsExtension([NotNull] NamingConventionsOptionsExtension copyFrom)
|
||||
public virtual DbContextOptionsExtensionInfo Info => _info ??= new ExtensionInfo(this);
|
||||
|
||||
protected virtual NamingConventionsOptionsExtension Clone() => new(this);
|
||||
|
||||
internal virtual NamingConvention NamingConvention => _namingConvention;
|
||||
internal virtual CultureInfo Culture => _culture;
|
||||
|
||||
public virtual NamingConventionsOptionsExtension WithoutNaming()
|
||||
{
|
||||
var clone = Clone();
|
||||
clone._namingConvention = NamingConvention.None;
|
||||
return clone;
|
||||
}
|
||||
|
||||
public virtual NamingConventionsOptionsExtension WithSnakeCaseNamingConvention(CultureInfo culture = null)
|
||||
{
|
||||
var clone = Clone();
|
||||
clone._namingConvention = NamingConvention.SnakeCase;
|
||||
clone._culture = culture;
|
||||
return clone;
|
||||
}
|
||||
|
||||
public virtual NamingConventionsOptionsExtension WithLowerCaseNamingConvention(CultureInfo culture = null)
|
||||
{
|
||||
var clone = Clone();
|
||||
clone._namingConvention = NamingConvention.LowerCase;
|
||||
clone._culture = culture;
|
||||
return clone;
|
||||
}
|
||||
|
||||
public virtual NamingConventionsOptionsExtension WithUpperCaseNamingConvention(CultureInfo culture = null)
|
||||
{
|
||||
var clone = Clone();
|
||||
clone._namingConvention = NamingConvention.UpperCase;
|
||||
clone._culture = culture;
|
||||
return clone;
|
||||
}
|
||||
|
||||
public virtual NamingConventionsOptionsExtension WithUpperSnakeCaseNamingConvention(CultureInfo culture = null)
|
||||
{
|
||||
var clone = Clone();
|
||||
clone._namingConvention = NamingConvention.UpperSnakeCase;
|
||||
clone._culture = culture;
|
||||
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)
|
||||
=> services.AddEntityFrameworkNamingConventions();
|
||||
|
||||
private sealed class ExtensionInfo : DbContextOptionsExtensionInfo
|
||||
{
|
||||
private string _logFragment;
|
||||
|
||||
public ExtensionInfo(IDbContextOptionsExtension extension) : base(extension) {}
|
||||
|
||||
private new NamingConventionsOptionsExtension Extension
|
||||
=> (NamingConventionsOptionsExtension)base.Extension;
|
||||
|
||||
public override bool IsDatabaseProvider => false;
|
||||
|
||||
public override string LogFragment
|
||||
{
|
||||
_namingConvention = copyFrom._namingConvention;
|
||||
_culture = copyFrom._culture;
|
||||
}
|
||||
|
||||
public virtual DbContextOptionsExtensionInfo Info => _info ??= new ExtensionInfo(this);
|
||||
|
||||
protected virtual NamingConventionsOptionsExtension Clone() => new(this);
|
||||
|
||||
internal virtual NamingConvention NamingConvention => _namingConvention;
|
||||
internal virtual CultureInfo Culture => _culture;
|
||||
|
||||
public virtual NamingConventionsOptionsExtension WithoutNaming()
|
||||
{
|
||||
var clone = Clone();
|
||||
clone._namingConvention = NamingConvention.None;
|
||||
return clone;
|
||||
}
|
||||
|
||||
public virtual NamingConventionsOptionsExtension WithSnakeCaseNamingConvention(CultureInfo culture = null)
|
||||
{
|
||||
var clone = Clone();
|
||||
clone._namingConvention = NamingConvention.SnakeCase;
|
||||
clone._culture = culture;
|
||||
return clone;
|
||||
}
|
||||
|
||||
public virtual NamingConventionsOptionsExtension WithLowerCaseNamingConvention(CultureInfo culture = null)
|
||||
{
|
||||
var clone = Clone();
|
||||
clone._namingConvention = NamingConvention.LowerCase;
|
||||
clone._culture = culture;
|
||||
return clone;
|
||||
}
|
||||
|
||||
public virtual NamingConventionsOptionsExtension WithUpperCaseNamingConvention(CultureInfo culture = null)
|
||||
{
|
||||
var clone = Clone();
|
||||
clone._namingConvention = NamingConvention.UpperCase;
|
||||
clone._culture = culture;
|
||||
return clone;
|
||||
}
|
||||
|
||||
public virtual NamingConventionsOptionsExtension WithUpperSnakeCaseNamingConvention(CultureInfo culture = null)
|
||||
{
|
||||
var clone = Clone();
|
||||
clone._namingConvention = NamingConvention.UpperSnakeCase;
|
||||
clone._culture = culture;
|
||||
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)
|
||||
=> services.AddEntityFrameworkNamingConventions();
|
||||
|
||||
private sealed class ExtensionInfo : DbContextOptionsExtensionInfo
|
||||
{
|
||||
private string _logFragment;
|
||||
|
||||
public ExtensionInfo(IDbContextOptionsExtension extension) : base(extension) {}
|
||||
|
||||
private new NamingConventionsOptionsExtension Extension
|
||||
=> (NamingConventionsOptionsExtension)base.Extension;
|
||||
|
||||
public override bool IsDatabaseProvider => false;
|
||||
|
||||
public override string LogFragment
|
||||
get
|
||||
{
|
||||
get
|
||||
if (_logFragment == null)
|
||||
{
|
||||
if (_logFragment == null)
|
||||
var builder = new StringBuilder();
|
||||
|
||||
builder.Append(Extension._namingConvention switch
|
||||
{
|
||||
var builder = new StringBuilder();
|
||||
NamingConvention.SnakeCase => "using snake-case naming ",
|
||||
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)
|
||||
});
|
||||
|
||||
builder.Append(Extension._namingConvention switch
|
||||
{
|
||||
NamingConvention.SnakeCase => "using snake-case naming ",
|
||||
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)
|
||||
});
|
||||
|
||||
if (Extension._culture is null)
|
||||
{
|
||||
builder
|
||||
.Append(" (culture=")
|
||||
.Append(Extension._culture)
|
||||
.Append(")");
|
||||
}
|
||||
|
||||
_logFragment = builder.ToString();
|
||||
if (Extension._culture is null)
|
||||
{
|
||||
builder
|
||||
.Append(" (culture=")
|
||||
.Append(Extension._culture)
|
||||
.Append(")");
|
||||
}
|
||||
|
||||
return _logFragment;
|
||||
_logFragment = builder.ToString();
|
||||
}
|
||||
|
||||
return _logFragment;
|
||||
}
|
||||
}
|
||||
|
||||
public override int GetServiceProviderHashCode()
|
||||
public override int GetServiceProviderHashCode()
|
||||
{
|
||||
var hashCode = Extension._namingConvention.GetHashCode();
|
||||
hashCode = (hashCode * 3) ^ (Extension._culture?.GetHashCode() ?? 0);
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
public override bool ShouldUseSameServiceProvider(DbContextOptionsExtensionInfo other)
|
||||
=> other is ExtensionInfo;
|
||||
|
||||
public override void PopulateDebugInfo(IDictionary<string, string> debugInfo)
|
||||
{
|
||||
debugInfo["Naming:UseNamingConvention"]
|
||||
= Extension._namingConvention.GetHashCode().ToString(CultureInfo.InvariantCulture);
|
||||
if (Extension._culture != null)
|
||||
{
|
||||
var hashCode = Extension._namingConvention.GetHashCode();
|
||||
hashCode = (hashCode * 3) ^ (Extension._culture?.GetHashCode() ?? 0);
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
public override bool ShouldUseSameServiceProvider(DbContextOptionsExtensionInfo other)
|
||||
=> other is ExtensionInfo;
|
||||
|
||||
public override void PopulateDebugInfo(IDictionary<string, string> debugInfo)
|
||||
{
|
||||
debugInfo["Naming:UseNamingConvention"]
|
||||
= Extension._namingConvention.GetHashCode().ToString(CultureInfo.InvariantCulture);
|
||||
if (Extension._culture != null)
|
||||
{
|
||||
debugInfo["Naming:Culture"]
|
||||
= Extension._culture.GetHashCode().ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
debugInfo["Naming:Culture"]
|
||||
= Extension._culture.GetHashCode().ToString(CultureInfo.InvariantCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,37 +2,37 @@ using System;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
|
||||
namespace EFCore.NamingConventions.Internal
|
||||
namespace EFCore.NamingConventions.Internal;
|
||||
|
||||
public class SnakeCaseNameRewriter : INameRewriter
|
||||
{
|
||||
public class SnakeCaseNameRewriter : INameRewriter
|
||||
private readonly CultureInfo _culture;
|
||||
|
||||
public SnakeCaseNameRewriter(CultureInfo culture) => _culture = culture;
|
||||
|
||||
public virtual string RewriteName(string name)
|
||||
{
|
||||
private readonly CultureInfo _culture;
|
||||
|
||||
public SnakeCaseNameRewriter(CultureInfo culture) => _culture = culture;
|
||||
|
||||
public virtual string RewriteName(string name)
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
return name;
|
||||
}
|
||||
|
||||
var builder = new StringBuilder(name.Length + Math.Min(2, name.Length / 5));
|
||||
var previousCategory = default(UnicodeCategory?);
|
||||
|
||||
for (var currentIndex = 0; currentIndex < name.Length; currentIndex++)
|
||||
{
|
||||
var currentChar = name[currentIndex];
|
||||
if (currentChar == '_')
|
||||
{
|
||||
return name;
|
||||
builder.Append('_');
|
||||
previousCategory = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
var builder = new StringBuilder(name.Length + Math.Min(2, name.Length / 5));
|
||||
var previousCategory = default(UnicodeCategory?);
|
||||
|
||||
for (var currentIndex = 0; currentIndex < name.Length; currentIndex++)
|
||||
var currentCategory = char.GetUnicodeCategory(currentChar);
|
||||
switch (currentCategory)
|
||||
{
|
||||
var currentChar = name[currentIndex];
|
||||
if (currentChar == '_')
|
||||
{
|
||||
builder.Append('_');
|
||||
previousCategory = null;
|
||||
continue;
|
||||
}
|
||||
|
||||
var currentCategory = char.GetUnicodeCategory(currentChar);
|
||||
switch (currentCategory)
|
||||
{
|
||||
case UnicodeCategory.UppercaseLetter:
|
||||
case UnicodeCategory.TitlecaseLetter:
|
||||
if (previousCategory == UnicodeCategory.SpaceSeparator ||
|
||||
@@ -63,13 +63,12 @@ namespace EFCore.NamingConventions.Internal
|
||||
previousCategory = UnicodeCategory.SpaceSeparator;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
builder.Append(currentChar);
|
||||
previousCategory = currentCategory;
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
builder.Append(currentChar);
|
||||
previousCategory = currentCategory;
|
||||
}
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
using System.Globalization;
|
||||
|
||||
namespace EFCore.NamingConventions.Internal
|
||||
{
|
||||
public class UpperCaseNameRewriter : INameRewriter
|
||||
{
|
||||
private readonly CultureInfo _culture;
|
||||
namespace EFCore.NamingConventions.Internal;
|
||||
|
||||
public UpperCaseNameRewriter(CultureInfo culture) => _culture = culture;
|
||||
public string RewriteName(string name) => name.ToUpper(_culture);
|
||||
}
|
||||
}
|
||||
public class UpperCaseNameRewriter : INameRewriter
|
||||
{
|
||||
private readonly CultureInfo _culture;
|
||||
|
||||
public UpperCaseNameRewriter(CultureInfo culture) => _culture = culture;
|
||||
public string RewriteName(string name) => name.ToUpper(_culture);
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
using System.Globalization;
|
||||
|
||||
namespace EFCore.NamingConventions.Internal
|
||||
namespace EFCore.NamingConventions.Internal;
|
||||
|
||||
public class UpperSnakeCaseNameRewriter : SnakeCaseNameRewriter
|
||||
{
|
||||
public class UpperSnakeCaseNameRewriter : SnakeCaseNameRewriter
|
||||
{
|
||||
private readonly CultureInfo _culture;
|
||||
private readonly CultureInfo _culture;
|
||||
|
||||
public UpperSnakeCaseNameRewriter(CultureInfo culture) : base(culture) => _culture = culture;
|
||||
public UpperSnakeCaseNameRewriter(CultureInfo culture) : base(culture) => _culture = culture;
|
||||
|
||||
public override string RewriteName(string name) => base.RewriteName(name).ToUpper(_culture);
|
||||
}
|
||||
}
|
||||
public override string RewriteName(string name) => base.RewriteName(name).ToUpper(_culture);
|
||||
}
|
||||
@@ -4,103 +4,102 @@ using JetBrains.Annotations;
|
||||
using EFCore.NamingConventions.Internal;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Microsoft.EntityFrameworkCore
|
||||
namespace Microsoft.EntityFrameworkCore;
|
||||
|
||||
public static class NamingConventionsExtensions
|
||||
{
|
||||
public static class NamingConventionsExtensions
|
||||
public static DbContextOptionsBuilder UseSnakeCaseNamingConvention(
|
||||
[NotNull] this DbContextOptionsBuilder optionsBuilder , CultureInfo culture = null)
|
||||
{
|
||||
public static DbContextOptionsBuilder UseSnakeCaseNamingConvention(
|
||||
[NotNull] this DbContextOptionsBuilder optionsBuilder , CultureInfo culture = null)
|
||||
{
|
||||
Check.NotNull(optionsBuilder, nameof(optionsBuilder));
|
||||
Check.NotNull(optionsBuilder, nameof(optionsBuilder));
|
||||
|
||||
var extension = (optionsBuilder.Options.FindExtension<NamingConventionsOptionsExtension>()
|
||||
?? new NamingConventionsOptionsExtension())
|
||||
.WithSnakeCaseNamingConvention(culture);
|
||||
var extension = (optionsBuilder.Options.FindExtension<NamingConventionsOptionsExtension>()
|
||||
?? new NamingConventionsOptionsExtension())
|
||||
.WithSnakeCaseNamingConvention(culture);
|
||||
|
||||
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||
|
||||
return optionsBuilder;
|
||||
}
|
||||
|
||||
public static DbContextOptionsBuilder<TContext> UseSnakeCaseNamingConvention<TContext>(
|
||||
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder , CultureInfo culture = null)
|
||||
where TContext : DbContext
|
||||
=> (DbContextOptionsBuilder<TContext>)UseSnakeCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder, culture);
|
||||
|
||||
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(culture);
|
||||
|
||||
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||
|
||||
return optionsBuilder;
|
||||
}
|
||||
|
||||
public static DbContextOptionsBuilder<TContext> UseLowerCaseNamingConvention<TContext>(
|
||||
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder, CultureInfo culture = null)
|
||||
where TContext : DbContext
|
||||
=> (DbContextOptionsBuilder<TContext>)UseLowerCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder ,culture);
|
||||
|
||||
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(culture);
|
||||
|
||||
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||
|
||||
return optionsBuilder;
|
||||
}
|
||||
|
||||
public static DbContextOptionsBuilder<TContext> UseUpperCaseNamingConvention<TContext>(
|
||||
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder, CultureInfo culture = null)
|
||||
where TContext : DbContext
|
||||
=> (DbContextOptionsBuilder<TContext>)UseUpperCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder, culture);
|
||||
|
||||
public static DbContextOptionsBuilder UseUpperSnakeCaseNamingConvention(
|
||||
[NotNull] this DbContextOptionsBuilder optionsBuilder, CultureInfo culture = null)
|
||||
{
|
||||
Check.NotNull(optionsBuilder, nameof(optionsBuilder));
|
||||
|
||||
var extension = (optionsBuilder.Options.FindExtension<NamingConventionsOptionsExtension>()
|
||||
?? new NamingConventionsOptionsExtension())
|
||||
.WithUpperSnakeCaseNamingConvention(culture);
|
||||
|
||||
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||
|
||||
return optionsBuilder;
|
||||
}
|
||||
|
||||
public static DbContextOptionsBuilder<TContext> UseUpperSnakeCaseNamingConvention<TContext>(
|
||||
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder, CultureInfo culture = null)
|
||||
where TContext : DbContext
|
||||
=> (DbContextOptionsBuilder<TContext>)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<NamingConventionsOptionsExtension>()
|
||||
?? new NamingConventionsOptionsExtension())
|
||||
.WithCamelCaseNamingConvention(culture);
|
||||
|
||||
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||
|
||||
return optionsBuilder;
|
||||
}
|
||||
|
||||
public static DbContextOptionsBuilder<TContext> UseCamelCaseNamingConvention<TContext>(
|
||||
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder, CultureInfo culture = null)
|
||||
where TContext : DbContext
|
||||
=> (DbContextOptionsBuilder<TContext>)UseCamelCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder, culture);
|
||||
return optionsBuilder;
|
||||
}
|
||||
}
|
||||
|
||||
public static DbContextOptionsBuilder<TContext> UseSnakeCaseNamingConvention<TContext>(
|
||||
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder , CultureInfo culture = null)
|
||||
where TContext : DbContext
|
||||
=> (DbContextOptionsBuilder<TContext>)UseSnakeCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder, culture);
|
||||
|
||||
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(culture);
|
||||
|
||||
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||
|
||||
return optionsBuilder;
|
||||
}
|
||||
|
||||
public static DbContextOptionsBuilder<TContext> UseLowerCaseNamingConvention<TContext>(
|
||||
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder, CultureInfo culture = null)
|
||||
where TContext : DbContext
|
||||
=> (DbContextOptionsBuilder<TContext>)UseLowerCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder ,culture);
|
||||
|
||||
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(culture);
|
||||
|
||||
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||
|
||||
return optionsBuilder;
|
||||
}
|
||||
|
||||
public static DbContextOptionsBuilder<TContext> UseUpperCaseNamingConvention<TContext>(
|
||||
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder, CultureInfo culture = null)
|
||||
where TContext : DbContext
|
||||
=> (DbContextOptionsBuilder<TContext>)UseUpperCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder, culture);
|
||||
|
||||
public static DbContextOptionsBuilder UseUpperSnakeCaseNamingConvention(
|
||||
[NotNull] this DbContextOptionsBuilder optionsBuilder, CultureInfo culture = null)
|
||||
{
|
||||
Check.NotNull(optionsBuilder, nameof(optionsBuilder));
|
||||
|
||||
var extension = (optionsBuilder.Options.FindExtension<NamingConventionsOptionsExtension>()
|
||||
?? new NamingConventionsOptionsExtension())
|
||||
.WithUpperSnakeCaseNamingConvention(culture);
|
||||
|
||||
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||
|
||||
return optionsBuilder;
|
||||
}
|
||||
|
||||
public static DbContextOptionsBuilder<TContext> UseUpperSnakeCaseNamingConvention<TContext>(
|
||||
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder, CultureInfo culture = null)
|
||||
where TContext : DbContext
|
||||
=> (DbContextOptionsBuilder<TContext>)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<NamingConventionsOptionsExtension>()
|
||||
?? new NamingConventionsOptionsExtension())
|
||||
.WithCamelCaseNamingConvention(culture);
|
||||
|
||||
((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
|
||||
|
||||
return optionsBuilder;
|
||||
}
|
||||
|
||||
public static DbContextOptionsBuilder<TContext> UseCamelCaseNamingConvention<TContext>(
|
||||
[NotNull] this DbContextOptionsBuilder<TContext> optionsBuilder, CultureInfo culture = null)
|
||||
where TContext : DbContext
|
||||
=> (DbContextOptionsBuilder<TContext>)UseCamelCaseNamingConvention((DbContextOptionsBuilder)optionsBuilder, culture);
|
||||
}
|
||||
@@ -5,38 +5,37 @@ using EFCore.NamingConventions.Internal;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Microsoft.Extensions.DependencyInjection
|
||||
namespace Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
|
||||
/// </summary>
|
||||
public static class NamingConventionsServiceCollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods for <see cref="Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
|
||||
/// <para>
|
||||
/// Adds the services required for applying naming conventions in Entity Framework Core.
|
||||
/// You use this method when using dependency injection in your application, such as with ASP.NET.
|
||||
/// For more information on setting up dependency injection, see http://go.microsoft.com/fwlink/?LinkId=526890.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// You only need to use this functionality when you want Entity Framework to resolve the services it uses
|
||||
/// from an external dependency injection container. If you are not using an external
|
||||
/// dependency injection container, Entity Framework will take care of creating the services it requires.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public static class NamingConventionsServiceCollectionExtensions
|
||||
/// <param name="serviceCollection">The <see cref="IServiceCollection" /> to add services to.</param>
|
||||
/// <returns>
|
||||
/// The same service collection so that multiple calls can be chained.
|
||||
/// </returns>
|
||||
public static IServiceCollection AddEntityFrameworkNamingConventions(
|
||||
[NotNull] this IServiceCollection serviceCollection)
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// Adds the services required for applying naming conventions in Entity Framework Core.
|
||||
/// You use this method when using dependency injection in your application, such as with ASP.NET.
|
||||
/// For more information on setting up dependency injection, see http://go.microsoft.com/fwlink/?LinkId=526890.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// You only need to use this functionality when you want Entity Framework to resolve the services it uses
|
||||
/// from an external dependency injection container. If you are not using an external
|
||||
/// dependency injection container, Entity Framework will take care of creating the services it requires.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <param name="serviceCollection">The <see cref="IServiceCollection" /> to add services to.</param>
|
||||
/// <returns>
|
||||
/// The same service collection so that multiple calls can be chained.
|
||||
/// </returns>
|
||||
public static IServiceCollection AddEntityFrameworkNamingConventions(
|
||||
[NotNull] this IServiceCollection serviceCollection)
|
||||
{
|
||||
Check.NotNull(serviceCollection, nameof(serviceCollection));
|
||||
Check.NotNull(serviceCollection, nameof(serviceCollection));
|
||||
|
||||
new EntityFrameworkServicesBuilder(serviceCollection)
|
||||
.TryAdd<IConventionSetPlugin, NamingConventionSetPlugin>();
|
||||
new EntityFrameworkServicesBuilder(serviceCollection)
|
||||
.TryAdd<IConventionSetPlugin, NamingConventionSetPlugin>();
|
||||
|
||||
return serviceCollection;
|
||||
}
|
||||
return serviceCollection;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user