Snootalogue/Data/SnootalogueContext.cs

47 lines
1.8 KiB
C#

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<Snootalogue.Models.Document> Document { get; set; }
public SnootalogueContext(
DbContextOptions<SnootalogueContext> options)
: base(options) {
}
protected override void OnModelCreating(ModelBuilder modelBuilder) {
modelBuilder.Entity<Document>().Property(item => item.Authors).HasJsonConversion<List<string>>();
modelBuilder.Entity<Document>().Property(item => item.Tags).HasJsonConversion<List<string>>();
}
}
public static class JsonConversion {
// big beebus thanks to https://stackoverflow.com/a/59185869
public static PropertyBuilder<T> HasJsonConversion<T>(this PropertyBuilder<T> propertyBuilder) where T : class, new() {
ValueConverter<T, string> converter = new ValueConverter<T, string>(
value => JsonSerializer.Serialize(value, null),
value => JsonSerializer.Deserialize<T>(value, null)
);
ValueComparer<T> comparer = new ValueComparer<T>(
(l, r) => JsonSerializer.Serialize(l, null) == JsonSerializer.Serialize(r, null),
value => value == null ? 0 : JsonSerializer.Serialize(value, null).GetHashCode(),
value => JsonSerializer.Deserialize<T>(JsonSerializer.Serialize(value, null), null)
);
propertyBuilder.HasConversion(converter);
propertyBuilder.Metadata.SetValueConverter(converter);
propertyBuilder.Metadata.SetValueComparer(comparer);
propertyBuilder.HasColumnType("jsonb");
return propertyBuilder;
}
}
}