I18n через jsonb-поля

This commit is contained in:
2025-04-24 15:53:05 +04:00
parent 35b571eb57
commit 31ad99ade5
33 changed files with 409 additions and 264 deletions
+59 -15
View File
@@ -1,11 +1,13 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
using Pf2eModel.Model;
using Pf2eModel.Model.Base;
using Pf2eModel.Model.Base.Keywords;
using Pf2eModel.Model.Base.Source;
using Pf2eModel.Model.Base.Targets;
using Pf2eModel.Model.Common;
using Pf2eModel.Model.Common.I18n;
using Pf2eModel.Model.Enum;
using Pf2eModel.Model.Structure;
using Pf2eModel.Model.Structure.AncestryRelation;
@@ -15,6 +17,8 @@ using Pf2eModel.Model.Structure.ClassRelation;
using Pf2eModel.Model.Structure.DeityRelation;
using Pf2eModel.Model.Structure.FeatRelation;
using Pf2eModel.Model.Structure.SpellRelation;
using System.Linq.Expressions;
using System.Reflection;
namespace Pf2eModel;
@@ -30,6 +34,32 @@ public partial class Pf2eDbContext
DefineBase(modelBuilder);
DefineCommon(modelBuilder);
DefineStructure(modelBuilder);
DefineMethods(modelBuilder);
}
private void BindEntity<T>(EntityTypeBuilder<T> entity) where T : class, IEntity
{
entity.HasOne(entity => entity.Entity)
.WithOne()
.HasForeignKey<T>(entity => entity.Id)
.IsRequired();
}
private void BindLocaleString<T>(EntityTypeBuilder<T> entity, Expression<Func<T, LocaleString>> func) where T : class
{
/*
entity.OwnsMany(func, d =>
{
d.ToJson();
});
*/
entity.Property(func)
.HasConversion(
v => v.Serialize(),
v => LocaleString.Deserialize(v)
)
.HasColumnType("jsonb");
}
private void DefineEnums(ModelBuilder modelBuilder)
@@ -37,7 +67,7 @@ public partial class Pf2eDbContext
modelBuilder
.HasPostgresEnum<EntityType>()
.HasPostgresEnum<EntityRarity>()
.HasPostgresEnum<AliasType>()
.HasPostgresEnum<LocaleType>()
.HasPostgresEnum<TraitType>()
.HasPostgresEnum<ActionCategory>()
.HasPostgresEnum<Size>()
@@ -62,15 +92,12 @@ public partial class Pf2eDbContext
{
modelBuilder.Entity<Entity>(entity =>
{
BindLocaleString(entity, e => e.Name);
entity.HasMany(e => e.Traits).WithMany(t => t.Entities);
entity.HasMany(e => e.Keywords).WithMany(t => t.Entities);
// EntityAlias
entity.HasMany(e => e.Aliases).WithOne(e => e.Entity)
.HasForeignKey(e => e.EntityId)
.OnDelete(DeleteBehavior.Cascade);
// EntitySource
entity.HasMany(e => e.Sources).WithOne(e => e.Entity)
.HasForeignKey(e => e.EntityId)
@@ -81,7 +108,6 @@ public partial class Pf2eDbContext
.HasForeignKey(e => e.EntityId)
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity<EntityAlias>(entity => { });
// Source
modelBuilder.Entity<Source>(entity =>
@@ -124,14 +150,6 @@ public partial class Pf2eDbContext
modelBuilder.Entity<Training>(entity => { });
}
private void BindEntity<T>(EntityTypeBuilder<T> entity) where T : class, IEntity
{
entity.HasOne(entity => entity.Entity)
.WithOne()
.HasForeignKey<T>(entity => entity.Id)
.IsRequired();
}
private void DefineStructure(ModelBuilder modelBuilder)
{
// Action
@@ -341,4 +359,30 @@ public partial class Pf2eDbContext
BindEntity(entity);
});
}
private void DefineMethods(ModelBuilder modelBuilder)
{
MethodInfo localeSearch = typeof(Pf2eDbContext).GetMethod(nameof(LocaleSearch), BindingFlags.Static | BindingFlags.Public, [typeof(LocaleString), typeof(string)])!;
modelBuilder.HasDbFunction(localeSearch, builder =>
{
builder.HasName("locale_search");
builder.HasParameter("data").HasStoreType("jsonb");
builder.HasParameter("search_value");
});
MethodInfo localeSearchArray = typeof(Pf2eDbContext).GetMethod(nameof(LocaleSearchArray), BindingFlags.Static | BindingFlags.Public, [typeof(LocaleString), typeof(IEnumerable<string>)])!;
modelBuilder.HasDbFunction(localeSearchArray, builder =>
{
builder.HasName("locale_search_array");
builder.HasParameter("data").HasStoreType("jsonb");
builder.HasParameter("search_values");
});
}
public static bool LocaleSearch(LocaleString data, string search_value)
=> throw new InvalidOperationException("Only for LINQ translation");
public static bool LocaleSearchArray(LocaleString data, IEnumerable<string> search_values)
=> throw new InvalidOperationException("Only for LINQ translation");
}