using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.ChangeTracking; using Snootalogue.Models; using System.Text.Json; using System.Text.Json.Serialization; using System.Collections.Generic; namespace Snootalogue.Data { public class SnootalogueContext : DbContext { public DbSet Document { get; set; } public SnootalogueContext( DbContextOptions options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity().Property(item => item.Authors).HasJsonConversion>(); modelBuilder.Entity().Property(item => item.Tags).HasJsonConversion>(); } } public static class JsonConversion { // big beebus thanks to https://stackoverflow.com/a/59185869 public static PropertyBuilder HasJsonConversion(this PropertyBuilder propertyBuilder) where T : class, new() { ValueConverter converter = new ValueConverter( value => JsonSerializer.Serialize(value, null), value => JsonSerializer.Deserialize(value, null) ); ValueComparer comparer = new ValueComparer( (l, r) => JsonSerializer.Serialize(l, null) == JsonSerializer.Serialize(r, null), value => value == null ? 0 : JsonSerializer.Serialize(value, null).GetHashCode(), value => JsonSerializer.Deserialize(JsonSerializer.Serialize(value, null), null) ); propertyBuilder.HasConversion(converter); propertyBuilder.Metadata.SetValueConverter(converter); propertyBuilder.Metadata.SetValueComparer(comparer); propertyBuilder.HasColumnType("jsonb"); return propertyBuilder; } } }