diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreApplicationConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreApplicationConfiguration.cs index 805eb02a..c6b9520e 100644 --- a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreApplicationConfiguration.cs +++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreApplicationConfiguration.cs @@ -7,6 +7,7 @@ using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Text.Json; +using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.IdentityModel.Tokens; using OpenIddict.EntityFrameworkCore.Models; @@ -67,7 +68,8 @@ public sealed class OpenIddictEntityFrameworkCoreApplicationConfiguration< builder.Property(static application => application.DisplayNames) .HasConversion( static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringString), - static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString)); + static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString), + CreateDictionaryComparer()); builder.HasKey(static application => application.Id); @@ -88,12 +90,14 @@ public sealed class OpenIddictEntityFrameworkCoreApplicationConfiguration< builder.Property(static application => application.Properties) .HasConversion( static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement), - static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement)); + static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement), + CreateDictionaryComparer()); builder.Property(static application => application.Settings) .HasConversion( static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringString), - static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString)); + static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString), + CreateDictionaryComparer()); builder.HasMany(static application => application.Tokens) .WithOne(static token => token.Application!) @@ -101,5 +105,10 @@ public sealed class OpenIddictEntityFrameworkCoreApplicationConfiguration< .IsRequired(required: false); builder.ToTable("OpenIddictApplications"); + + static ValueComparer CreateDictionaryComparer() => new ValueComparer>( + static (left, right) => ReferenceEquals(left, right) || (left != null && right != null && left.SequenceEqual(right)), + static value => value.Aggregate(0, static (hash, value) => HashCode.Combine(hash, value)), + static value => value.ToDictionary()); } } diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreAuthorizationConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreAuthorizationConfiguration.cs index bcf93313..9f05ae69 100644 --- a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreAuthorizationConfiguration.cs +++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreAuthorizationConfiguration.cs @@ -7,6 +7,7 @@ using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Text.Json; +using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Metadata.Builders; using OpenIddict.EntityFrameworkCore.Models; @@ -62,7 +63,8 @@ public sealed class OpenIddictEntityFrameworkCoreAuthorizationConfiguration< builder.Property(static authorization => authorization.Properties) .HasConversion( static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement), - static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement)); + static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement), + CreateDictionaryComparer()); builder.Property(static authorization => authorization.Status) .HasMaxLength(50); @@ -80,5 +82,10 @@ public sealed class OpenIddictEntityFrameworkCoreAuthorizationConfiguration< .HasMaxLength(50); builder.ToTable("OpenIddictAuthorizations"); + + static ValueComparer CreateDictionaryComparer() => new ValueComparer>( + static (left, right) => ReferenceEquals(left, right) || (left != null && right != null && left.SequenceEqual(right)), + static value => value.Aggregate(0, static (hash, value) => HashCode.Combine(hash, value)), + static value => value.ToDictionary()); } } diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreResourceConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreResourceConfiguration.cs index 1b762a77..6a4ac701 100644 --- a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreResourceConfiguration.cs +++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreResourceConfiguration.cs @@ -7,6 +7,7 @@ using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Text.Json; +using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Metadata.Builders; using OpenIddict.EntityFrameworkCore.Models; @@ -39,12 +40,14 @@ public sealed class OpenIddictEntityFrameworkCoreResourceConfiguration< builder.Property(static resource => resource.Descriptions) .HasConversion( static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringString), - static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString)); + static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString), + CreateDictionaryComparer()); builder.Property(static resource => resource.DisplayNames) .HasConversion( static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringString), - static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString)); + static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString), + CreateDictionaryComparer()); builder.HasKey(static resource => resource.Id); @@ -66,8 +69,14 @@ public sealed class OpenIddictEntityFrameworkCoreResourceConfiguration< builder.Property(static resource => resource.Properties) .HasConversion( static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement), - static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement)); + static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement), + CreateDictionaryComparer()); builder.ToTable("OpenIddictResources"); + + static ValueComparer CreateDictionaryComparer() => new ValueComparer>( + static (left, right) => ReferenceEquals(left, right) || (left != null && right != null && left.SequenceEqual(right)), + static value => value.Aggregate(0, static (hash, value) => HashCode.Combine(hash, value)), + static value => value.ToDictionary()); } } diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreScopeConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreScopeConfiguration.cs index 6ce2b52d..bd251dad 100644 --- a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreScopeConfiguration.cs +++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreScopeConfiguration.cs @@ -7,6 +7,7 @@ using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Text.Json; +using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Metadata.Builders; using OpenIddict.EntityFrameworkCore.Models; @@ -39,12 +40,14 @@ public sealed class OpenIddictEntityFrameworkCoreScopeConfiguration< builder.Property(static scope => scope.Descriptions) .HasConversion( static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringString), - static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString)); + static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString), + CreateDictionaryComparer()); builder.Property(static scope => scope.DisplayNames) .HasConversion( static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringString), - static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString)); + static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringString), + CreateDictionaryComparer()); builder.HasKey(static scope => scope.Id); @@ -66,8 +69,14 @@ public sealed class OpenIddictEntityFrameworkCoreScopeConfiguration< builder.Property(static scope => scope.Properties) .HasConversion( static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement), - static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement)); + static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement), + CreateDictionaryComparer()); builder.ToTable("OpenIddictScopes"); + + static ValueComparer CreateDictionaryComparer() => new ValueComparer>( + static (left, right) => ReferenceEquals(left, right) || (left != null && right != null && left.SequenceEqual(right)), + static value => value.Aggregate(0, static (hash, value) => HashCode.Combine(hash, value)), + static value => value.ToDictionary()); } } diff --git a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreTokenConfiguration.cs b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreTokenConfiguration.cs index dc1b39aa..03a88ebe 100644 --- a/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreTokenConfiguration.cs +++ b/src/OpenIddict.EntityFrameworkCore/Configurations/OpenIddictEntityFrameworkCoreTokenConfiguration.cs @@ -7,6 +7,7 @@ using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Text.Json; +using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Metadata.Builders; using OpenIddict.EntityFrameworkCore.Models; @@ -74,11 +75,17 @@ public sealed class OpenIddictEntityFrameworkCoreTokenConfiguration< builder.Property(static token => token.Properties) .HasConversion( static value => JsonSerializer.Serialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement), - static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement)); + static value => JsonSerializer.Deserialize(value, OpenIddictSerializer.Default.IDictionaryStringJsonElement), + CreateDictionaryComparer()); builder.Property(static token => token.Type) .HasMaxLength(150); builder.ToTable("OpenIddictTokens"); + + static ValueComparer CreateDictionaryComparer() => new ValueComparer>( + static (left, right) => ReferenceEquals(left, right) || (left != null && right != null && left.SequenceEqual(right)), + static value => value.Aggregate(0, static (hash, value) => HashCode.Combine(hash, value)), + static value => value.ToDictionary()); } }