74 lines
2.3 KiB
C#
74 lines
2.3 KiB
C#
using System.Text;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.EntityFrameworkCore.Metadata;
|
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
|
|
|
namespace Tiku.Infrastructure.Persistence;
|
|
|
|
internal static class ModelBuilderExtensions
|
|
{
|
|
public static void UseSnakeCaseIdentifiers(this ModelBuilder modelBuilder)
|
|
{
|
|
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
|
|
{
|
|
foreach (var property in entityType.GetProperties())
|
|
{
|
|
property.SetColumnName(ToSnakeCase(property.Name));
|
|
}
|
|
|
|
foreach (var key in entityType.GetKeys())
|
|
{
|
|
if (key.GetName() is { } keyName)
|
|
{
|
|
key.SetName(ToSnakeCase(keyName));
|
|
}
|
|
}
|
|
|
|
foreach (var foreignKey in entityType.GetForeignKeys())
|
|
{
|
|
if (foreignKey.GetConstraintName() is { } constraintName)
|
|
{
|
|
foreignKey.SetConstraintName(ToSnakeCase(constraintName));
|
|
}
|
|
}
|
|
|
|
foreach (var index in entityType.GetIndexes())
|
|
{
|
|
if (index.GetDatabaseName() is { } indexName)
|
|
{
|
|
index.SetDatabaseName(ToSnakeCase(indexName));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static string ToSnakeCase(string value)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(value))
|
|
{
|
|
return value;
|
|
}
|
|
|
|
var builder = new StringBuilder(value.Length + 8);
|
|
for (var index = 0; index < value.Length; index++)
|
|
{
|
|
var character = value[index];
|
|
if (char.IsUpper(character) && index > 0 &&
|
|
(char.IsLower(value[index - 1]) ||
|
|
index + 1 < value.Length && char.IsLower(value[index + 1])))
|
|
{
|
|
builder.Append('_');
|
|
}
|
|
|
|
builder.Append(char.ToLowerInvariant(character));
|
|
}
|
|
|
|
return builder.ToString();
|
|
}
|
|
}
|
|
|
|
internal sealed class SnakeCaseEnumConverter<TEnum>() : ValueConverter<TEnum, string>(
|
|
value => ModelBuilderExtensions.ToSnakeCase(value.ToString()),
|
|
value => Enum.Parse<TEnum>(value.Replace("_", string.Empty), true))
|
|
where TEnum : struct, Enum;
|