From eb3c0b555da618424cc1294625c47e5b2be7caa7 Mon Sep 17 00:00:00 2001 From: Steven Giesel Date: Sun, 10 Nov 2024 11:20:00 +0100 Subject: [PATCH] Make it work on MySQL Again --- Directory.Packages.props | 10 +++++----- .../Sql/Mapping/BlogPostConfiguration.cs | 18 +++++++++++++++++- .../Sql/Mapping/JsonArrayConverter.cs | 16 ++++++++++++++++ .../Mapping/SimilarBlogPostConfiguration.cs | 18 +++++++++++++++++- 4 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 src/LinkDotNet.Blog.Infrastructure/Persistence/Sql/Mapping/JsonArrayConverter.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index 93a8b30c..97c7f9eb 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -8,12 +8,12 @@ - - - + + + - + @@ -41,4 +41,4 @@ - \ No newline at end of file + diff --git a/src/LinkDotNet.Blog.Infrastructure/Persistence/Sql/Mapping/BlogPostConfiguration.cs b/src/LinkDotNet.Blog.Infrastructure/Persistence/Sql/Mapping/BlogPostConfiguration.cs index 01919252..e06f3461 100644 --- a/src/LinkDotNet.Blog.Infrastructure/Persistence/Sql/Mapping/BlogPostConfiguration.cs +++ b/src/LinkDotNet.Blog.Infrastructure/Persistence/Sql/Mapping/BlogPostConfiguration.cs @@ -1,11 +1,20 @@ +using System; +using System.Text.Json; using LinkDotNet.Blog.Domain; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using MySql.EntityFrameworkCore.Extensions; namespace LinkDotNet.Blog.Infrastructure.Persistence.Sql.Mapping; internal sealed class BlogPostConfiguration : IEntityTypeConfiguration { + private readonly DatabaseFacade databaseFacade; + + public BlogPostConfiguration(DatabaseFacade databaseFacade) + => this.databaseFacade = databaseFacade; + public void Configure(EntityTypeBuilder builder) { builder.HasKey(c => c.Id); @@ -19,7 +28,14 @@ public void Configure(EntityTypeBuilder builder) builder.Property(x => x.ShortDescription).IsRequired(); builder.Property(x => x.Likes).IsRequired(); builder.Property(x => x.IsPublished).IsRequired(); - builder.Property(x => x.Tags).HasMaxLength(2096); + + var tags = builder.Property(x => x.Tags).HasMaxLength(2048); + + if (databaseFacade.IsMySql()) + { + // MySQL EF Driver does not support arrays out of the box so we have to json serialize and deserialize them + tags.HasConversion(); + } builder.HasIndex(x => new { x.IsPublished, x.UpdatedDate }) .HasDatabaseName("IX_BlogPosts_IsPublished_UpdatedDate") diff --git a/src/LinkDotNet.Blog.Infrastructure/Persistence/Sql/Mapping/JsonArrayConverter.cs b/src/LinkDotNet.Blog.Infrastructure/Persistence/Sql/Mapping/JsonArrayConverter.cs new file mode 100644 index 00000000..224ccc7b --- /dev/null +++ b/src/LinkDotNet.Blog.Infrastructure/Persistence/Sql/Mapping/JsonArrayConverter.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Text.Json; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace LinkDotNet.Blog.Infrastructure.Persistence.Sql.Mapping; + +internal sealed class JsonArrayConverter : ValueConverter, string> +{ + public JsonArrayConverter() : base( + v => JsonSerializer.Serialize(v, JsonSerializerOptions.Default), + v => JsonSerializer.Deserialize(v, JsonSerializerOptions.Default) ?? + Array.Empty()) + { + } +} diff --git a/src/LinkDotNet.Blog.Infrastructure/Persistence/Sql/Mapping/SimilarBlogPostConfiguration.cs b/src/LinkDotNet.Blog.Infrastructure/Persistence/Sql/Mapping/SimilarBlogPostConfiguration.cs index d96aea96..6faa5774 100644 --- a/src/LinkDotNet.Blog.Infrastructure/Persistence/Sql/Mapping/SimilarBlogPostConfiguration.cs +++ b/src/LinkDotNet.Blog.Infrastructure/Persistence/Sql/Mapping/SimilarBlogPostConfiguration.cs @@ -1,17 +1,33 @@ using LinkDotNet.Blog.Domain; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata.Builders; +using MySql.EntityFrameworkCore.Extensions; namespace LinkDotNet.Blog.Infrastructure.Persistence.Sql.Mapping; internal sealed class SimilarBlogPostConfiguration : IEntityTypeConfiguration { + private readonly DatabaseFacade database; + + public SimilarBlogPostConfiguration(DatabaseFacade database) + => this.database = database; + public void Configure(EntityTypeBuilder builder) { builder.HasKey(b => b.Id); builder.Property(b => b.Id) .IsUnicode(false) .ValueGeneratedOnAdd(); - builder.Property(b => b.SimilarBlogPostIds).HasMaxLength(450 * 3).IsRequired(); + + var similarBlogPosts = builder + .Property(b => b.SimilarBlogPostIds) + .HasMaxLength(450 * 3) + .IsRequired(); + + if (database.IsMySql()) + { + similarBlogPosts.HasConversion(); + } } }