From fb90db89f67c35006bc5afc2618d28d1aca2d1b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Wed, 7 Apr 2021 12:30:10 +0200 Subject: [PATCH] Convert DateTimeOffset to DateTime outside EF queries to work around a limitation in the Oracle MySQL provider --- .../Stores/OpenIddictEntityFrameworkAuthorizationStore.cs | 8 +++++++- .../Stores/OpenIddictEntityFrameworkTokenStore.cs | 8 +++++++- .../OpenIddictEntityFrameworkCoreAuthorizationStore.cs | 8 +++++++- .../Stores/OpenIddictEntityFrameworkCoreTokenStore.cs | 8 +++++++- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs index 65038a22..d8b7ab19 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkAuthorizationStore.cs @@ -633,9 +633,15 @@ namespace OpenIddict.EntityFramework // and thus prevent them from being concurrently modified outside this block. using var transaction = CreateTransaction(); + // Note: the Oracle MySQL provider doesn't support DateTimeOffset and is unable + // to create a SQL query with an expression calling DateTimeOffset.UtcDateTime. + // To work around this limitation, the threshold represented as a DateTimeOffset + // instance is manually converted to a UTC DateTime instance outside the query. + var date = threshold.UtcDateTime; + var authorizations = await (from authorization in Authorizations.Include(authorization => authorization.Tokens) - where authorization.CreationDate < threshold.UtcDateTime + where authorization.CreationDate < date where authorization.Status != Statuses.Valid || (authorization.Type == AuthorizationTypes.AdHoc && !authorization.Tokens.Any()) orderby authorization.Id diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs index 069c8b59..66598ec4 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictEntityFrameworkTokenStore.cs @@ -618,9 +618,15 @@ namespace OpenIddict.EntityFramework // and thus prevent them from being concurrently modified outside this block. using var transaction = CreateTransaction(); + // Note: the Oracle MySQL provider doesn't support DateTimeOffset and is unable + // to create a SQL query with an expression calling DateTimeOffset.UtcDateTime. + // To work around this limitation, the threshold represented as a DateTimeOffset + // instance is manually converted to a UTC DateTime instance outside the query. + var date = threshold.UtcDateTime; + var tokens = await (from token in Tokens - where token.CreationDate < threshold.UtcDateTime + where token.CreationDate < date where (token.Status != Statuses.Inactive && token.Status != Statuses.Valid) || (token.Authorization != null && token.Authorization.Status != Statuses.Valid) || token.ExpirationDate < DateTime.UtcNow diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs index fc7da06a..265b2d8e 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreAuthorizationStore.cs @@ -713,9 +713,15 @@ namespace OpenIddict.EntityFrameworkCore // and thus prevent them from being concurrently modified outside this block. using var transaction = await CreateTransactionAsync(); + // Note: the Oracle MySQL provider doesn't support DateTimeOffset and is unable + // to create a SQL query with an expression calling DateTimeOffset.UtcDateTime. + // To work around this limitation, the threshold represented as a DateTimeOffset + // instance is manually converted to a UTC DateTime instance outside the query. + var date = threshold.UtcDateTime; + var authorizations = await (from authorization in Authorizations.Include(authorization => authorization.Tokens).AsTracking() - where authorization.CreationDate < threshold.UtcDateTime + where authorization.CreationDate < date where authorization.Status != Statuses.Valid || (authorization.Type == AuthorizationTypes.AdHoc && !authorization.Tokens.Any()) orderby authorization.Id diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs index 99cbd945..7ad98c28 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictEntityFrameworkCoreTokenStore.cs @@ -681,9 +681,15 @@ namespace OpenIddict.EntityFrameworkCore // and thus prevent them from being concurrently modified outside this block. using var transaction = await CreateTransactionAsync(); + // Note: the Oracle MySQL provider doesn't support DateTimeOffset and is unable + // to create a SQL query with an expression calling DateTimeOffset.UtcDateTime. + // To work around this limitation, the threshold represented as a DateTimeOffset + // instance is manually converted to a UTC DateTime instance outside the query. + var date = threshold.UtcDateTime; + var tokens = await (from token in Tokens.AsTracking() - where token.CreationDate < threshold.UtcDateTime + where token.CreationDate < date where (token.Status != Statuses.Inactive && token.Status != Statuses.Valid) || (token.Authorization != null && token.Authorization.Status != Statuses.Valid) || token.ExpirationDate < DateTime.UtcNow