feat: add core persistence model

This commit is contained in:
xiong
2026-07-26 04:52:56 +08:00
parent f5109de879
commit 5dfb68d8cc
33 changed files with 6989 additions and 31 deletions

View File

@@ -0,0 +1,75 @@
using System.Text.Json;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Tiku.Domain.Common;
using Tiku.Domain.Tenancy;
namespace Tiku.Infrastructure.Persistence.Configurations;
internal static class ConfigurationSupport
{
public static void ConfigureEntity<TEntity>(
this EntityTypeBuilder<TEntity> builder,
string tableName)
where TEntity : Entity
{
builder.ToTable(tableName);
builder.HasKey(entity => entity.Id);
builder.Property(entity => entity.Id).HasDefaultValueSql("gen_random_uuid()");
}
public static void ConfigureTenantEntity<TEntity>(
this EntityTypeBuilder<TEntity> builder,
string tableName)
where TEntity : TenantEntity
{
builder.ConfigureEntity(tableName);
builder.HasAlternateKey(entity => new { entity.TenantId, entity.Id });
builder.HasOne<Tenant>()
.WithMany()
.HasForeignKey(entity => entity.TenantId)
.OnDelete(DeleteBehavior.Cascade);
}
public static void ConfigureTimestamps<TEntity>(this EntityTypeBuilder<TEntity> builder)
where TEntity : class, IHasTimestamps
{
builder.Property(entity => entity.CreatedAt).HasDefaultValueSql("now()");
builder.Property(entity => entity.UpdatedAt).HasDefaultValueSql("now()");
}
public static PropertyBuilder<JsonElement> IsJson(
this PropertyBuilder<JsonElement> property,
string defaultJson)
{
return property
.HasColumnType("jsonb")
.HasDefaultValueSql($"'{defaultJson}'::jsonb");
}
public static PropertyBuilder<TEnum> HasSnakeCaseEnum<TEnum>(
this PropertyBuilder<TEnum> property,
int maxLength = 32)
where TEnum : struct, Enum
{
return property
.HasConversion(new SnakeCaseEnumConverter<TEnum>())
.HasMaxLength(maxLength);
}
public static PropertyBuilder<TEnum?> HasNullableSnakeCaseEnum<TEnum>(
this PropertyBuilder<TEnum?> property,
int maxLength = 32)
where TEnum : struct, Enum
{
return property
.HasConversion(
value => value.HasValue
? ModelBuilderExtensions.ToSnakeCase(value.Value.ToString())
: null,
value => string.IsNullOrWhiteSpace(value)
? null
: Enum.Parse<TEnum>(value.Replace("_", string.Empty), true))
.HasMaxLength(maxLength);
}
}