Files
tiku-backend.net/Tiku.Infrastructure/Persistence/ModelBuilderExtensions.cs
2026-07-26 04:52:56 +08:00

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;