Browse Source

Update the Entity Framework Core stores to be compatible with QueryTrackingBehavior.NoTracking

pull/575/head
Kévin Chalet 8 years ago
parent
commit
866c61f399
  1. 23
      src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs
  2. 42
      src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs
  3. 1
      src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs
  4. 5
      src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs
  5. 6
      src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs
  6. 13
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs
  7. 33
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs
  8. 4
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs
  9. 22
      src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs

23
src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs

@ -281,7 +281,7 @@ namespace OpenIddict.Core
/// A <see cref="ValueTask{TResult}"/> that can be used to monitor the asynchronous operation,
/// whose result returns the application identifier associated with the authorization.
/// </returns>
public virtual async ValueTask<string> GetApplicationIdAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
public virtual ValueTask<string> GetApplicationIdAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
{
if (authorization == null)
{
@ -290,17 +290,22 @@ namespace OpenIddict.Core
if (authorization.Application != null)
{
return ConvertIdentifierToString(authorization.Application.Id);
return new ValueTask<string>(ConvertIdentifierToString(authorization.Application.Id));
}
IQueryable<TKey> Query(IQueryable<TAuthorization> authorizations, TKey key)
=> from element in authorizations
where element.Id.Equals(key) &&
element.Application != null
select element.Application.Id;
async Task<string> RetrieveApplicationIdAsync()
{
IQueryable<TKey> Query(IQueryable<TAuthorization> authorizations, TKey key)
=> from element in authorizations
where element.Id.Equals(key) &&
element.Application != null
select element.Application.Id;
return ConvertIdentifierToString(await GetAsync(
(authorizations, key) => Query(authorizations, key), authorization.Id, cancellationToken));
}
return ConvertIdentifierToString(await GetAsync(
(authorizations, key) => Query(authorizations, key), authorization.Id, cancellationToken));
return new ValueTask<string>(RetrieveApplicationIdAsync());
}
/// <summary>

42
src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs

@ -239,7 +239,7 @@ namespace OpenIddict.Core
/// A <see cref="ValueTask{TResult}"/> that can be used to monitor the asynchronous operation,
/// whose result returns the application identifier associated with the token.
/// </returns>
public virtual async ValueTask<string> GetApplicationIdAsync([NotNull] TToken token, CancellationToken cancellationToken)
public virtual ValueTask<string> GetApplicationIdAsync([NotNull] TToken token, CancellationToken cancellationToken)
{
if (token == null)
{
@ -248,16 +248,21 @@ namespace OpenIddict.Core
if (token.Application != null)
{
return ConvertIdentifierToString(token.Application.Id);
return new ValueTask<string>(ConvertIdentifierToString(token.Application.Id));
}
IQueryable<TKey> Query(IQueryable<TToken> tokens, TKey key)
=> from element in tokens
where element.Id.Equals(key) &&
element.Application != null
select element.Application.Id;
async Task<string> RetrieveApplicationIdAsync()
{
IQueryable<TKey> Query(IQueryable<TToken> tokens, TKey key)
=> from element in tokens
where element.Id.Equals(key) &&
element.Application != null
select element.Application.Id;
return ConvertIdentifierToString(await GetAsync((tokens, key) => Query(tokens, key), token.Id, cancellationToken));
}
return ConvertIdentifierToString(await GetAsync((tokens, key) => Query(tokens, key), token.Id, cancellationToken));
return new ValueTask<string>(RetrieveApplicationIdAsync());
}
/// <summary>
@ -269,7 +274,7 @@ namespace OpenIddict.Core
/// A <see cref="ValueTask{TResult}"/> that can be used to monitor the asynchronous operation,
/// whose result returns the authorization identifier associated with the token.
/// </returns>
public virtual async ValueTask<string> GetAuthorizationIdAsync([NotNull] TToken token, CancellationToken cancellationToken)
public virtual ValueTask<string> GetAuthorizationIdAsync([NotNull] TToken token, CancellationToken cancellationToken)
{
if (token == null)
{
@ -278,16 +283,21 @@ namespace OpenIddict.Core
if (token.Authorization != null)
{
return ConvertIdentifierToString(token.Authorization.Id);
return new ValueTask<string>(ConvertIdentifierToString(token.Authorization.Id));
}
IQueryable<TKey> Query(IQueryable<TToken> tokens, TKey key)
=> from element in tokens
where element.Id.Equals(key) &&
element.Authorization != null
select element.Authorization.Id;
async Task<string> RetrieveAuthorizationIdAsync()
{
IQueryable<TKey> Query(IQueryable<TToken> tokens, TKey key)
=> from element in tokens
where element.Id.Equals(key) &&
element.Authorization != null
select element.Authorization.Id;
return ConvertIdentifierToString(await GetAsync((tokens, key) => Query(tokens, key), token.Id, cancellationToken));
}
return ConvertIdentifierToString(await GetAsync((tokens, key) => Query(tokens, key), token.Id, cancellationToken));
return new ValueTask<string>(RetrieveAuthorizationIdAsync());
}
/// <summary>

1
src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs

@ -168,6 +168,7 @@ namespace OpenIddict.EntityFramework
Task<List<TToken>> ListTokensAsync()
=> (from token in Tokens
where token.Authorization == null
where token.Application.Id.Equals(application.Id)
select token).ToListAsync(cancellationToken);

5
src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs

@ -167,7 +167,7 @@ namespace OpenIddict.EntityFramework
where token.Authorization.Id.Equals(authorization.Id)
select token).ToListAsync(cancellationToken);
// Remove all the tokens associated with the application.
// Remove all the tokens associated with the authorization.
foreach (var token in await ListTokensAsync())
{
Tokens.Remove(token);
@ -383,7 +383,8 @@ namespace OpenIddict.EntityFramework
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
public override async Task SetApplicationIdAsync([NotNull] TAuthorization authorization, [CanBeNull] string identifier, CancellationToken cancellationToken)
public override async Task SetApplicationIdAsync([NotNull] TAuthorization authorization,
[CanBeNull] string identifier, CancellationToken cancellationToken)
{
if (authorization == null)
{

6
src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs

@ -407,7 +407,8 @@ namespace OpenIddict.EntityFramework
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
public override async Task SetApplicationIdAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken)
public override async Task SetApplicationIdAsync([NotNull] TToken token,
[CanBeNull] string identifier, CancellationToken cancellationToken)
{
if (token == null)
{
@ -452,7 +453,8 @@ namespace OpenIddict.EntityFramework
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
public override async Task SetAuthorizationIdAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken)
public override async Task SetAuthorizationIdAsync([NotNull] TToken token,
[CanBeNull] string identifier, CancellationToken cancellationToken)
{
if (token == null)
{

13
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs

@ -167,8 +167,8 @@ namespace OpenIddict.EntityFrameworkCore
// See https://github.com/openiddict/openiddict-core/issues/499 for more information.
Task<List<TAuthorization>> ListAuthorizationsAsync()
=> (from authorization in Authorizations.Include(authorization => authorization.Tokens)
join element in Applications on authorization.Application.Id equals element.Id
=> (from authorization in Authorizations.Include(authorization => authorization.Tokens).AsTracking()
join element in Applications.AsTracking() on authorization.Application.Id equals element.Id
where element.Id.Equals(application.Id)
select authorization).ToListAsync(cancellationToken);
@ -178,8 +178,9 @@ namespace OpenIddict.EntityFrameworkCore
// See https://github.com/openiddict/openiddict-core/issues/499 for more information.
Task<List<TToken>> ListTokensAsync()
=> (from token in Tokens
join element in Applications on token.Application.Id equals element.Id
=> (from token in Tokens.AsTracking()
where token.Authorization == null
join element in Applications.AsTracking() on token.Application.Id equals element.Id
where element.Id.Equals(application.Id)
select token).ToListAsync(cancellationToken);
@ -246,7 +247,7 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentNullException(nameof(query));
}
return query(Applications, state).FirstOrDefaultAsync(cancellationToken);
return query(Applications.AsTracking(), state).FirstOrDefaultAsync(cancellationToken);
}
/// <summary>
@ -270,7 +271,7 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentNullException(nameof(query));
}
return ImmutableArray.CreateRange(await query(Applications, state).ToListAsync(cancellationToken));
return ImmutableArray.CreateRange(await query(Applications.AsTracking(), state).ToListAsync(cancellationToken));
}
/// <summary>

33
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs

@ -170,12 +170,12 @@ namespace OpenIddict.EntityFrameworkCore
// See https://github.com/openiddict/openiddict-core/issues/499 for more information.
Task<List<TToken>> ListTokensAsync()
=> (from token in Tokens
join element in Authorizations on token.Authorization.Id equals element.Id
=> (from token in Tokens.AsTracking()
join element in Authorizations.AsTracking() on token.Authorization.Id equals element.Id
where element.Id.Equals(authorization.Id)
select token).ToListAsync(cancellationToken);
// Remove all the tokens associated with the application.
// Remove all the tokens associated with the authorization.
foreach (var token in await ListTokensAsync())
{
Context.Remove(token);
@ -217,9 +217,9 @@ namespace OpenIddict.EntityFrameworkCore
IQueryable<TAuthorization> Query(IQueryable<TAuthorization> authorizations,
IQueryable<TApplication> applications, TKey key, string principal)
=> from authorization in authorizations.Include(authorization => authorization.Application)
=> from authorization in authorizations.Include(authorization => authorization.Application).AsTracking()
where authorization.Subject == principal
join application in applications on authorization.Application.Id equals application.Id
join application in applications.AsTracking() on authorization.Application.Id equals application.Id
where application.Id.Equals(key)
select authorization;
@ -264,10 +264,9 @@ namespace OpenIddict.EntityFrameworkCore
IQueryable<TAuthorization> Query(IQueryable<TAuthorization> authorizations,
IQueryable<TApplication> applications, TKey key, string principal, string state)
=> from authorization in authorizations.Include(authorization => authorization.Application)
where authorization.Subject == principal &&
authorization.Status == state
join application in applications on authorization.Application.Id equals application.Id
=> from authorization in authorizations.Include(authorization => authorization.Application).AsTracking()
where authorization.Subject == principal && authorization.Status == state
join application in applications.AsTracking() on authorization.Application.Id equals application.Id
where application.Id.Equals(key)
select authorization;
@ -318,11 +317,11 @@ namespace OpenIddict.EntityFrameworkCore
IQueryable<TAuthorization> Query(IQueryable<TAuthorization> authorizations,
IQueryable<TApplication> applications, TKey key, string principal, string state, string kind)
=> from authorization in authorizations.Include(authorization => authorization.Application)
=> from authorization in authorizations.Include(authorization => authorization.Application).AsTracking()
where authorization.Subject == principal &&
authorization.Status == state &&
authorization.Type == kind
join application in applications on authorization.Application.Id equals application.Id
join application in applications.AsTracking() on authorization.Application.Id equals application.Id
where application.Id.Equals(key)
select authorization;
@ -416,7 +415,9 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentNullException(nameof(query));
}
return query(Authorizations.Include(authorization => authorization.Application), state).FirstOrDefaultAsync(cancellationToken);
return query(
Authorizations.Include(authorization => authorization.Application)
.AsTracking(), state).FirstOrDefaultAsync(cancellationToken);
}
/// <summary>
@ -441,7 +442,8 @@ namespace OpenIddict.EntityFrameworkCore
}
return ImmutableArray.CreateRange(await query(
Authorizations.Include(authorization => authorization.Application), state).ToListAsync(cancellationToken));
Authorizations.Include(authorization => authorization.Application)
.AsTracking(), state).ToListAsync(cancellationToken));
}
/// <summary>
@ -460,7 +462,7 @@ namespace OpenIddict.EntityFrameworkCore
IList<Exception> exceptions = null;
IQueryable<TAuthorization> Query(IQueryable<TAuthorization> authorizations, int offset)
=> (from authorization in authorizations.Include(authorization => authorization.Tokens)
=> (from authorization in authorizations.Include(authorization => authorization.Tokens).AsTracking()
where authorization.Status != OpenIddictConstants.Statuses.Valid ||
(authorization.Type == OpenIddictConstants.AuthorizationTypes.AdHoc &&
!authorization.Tokens.Any(token => token.Status == OpenIddictConstants.Statuses.Valid))
@ -545,7 +547,8 @@ namespace OpenIddict.EntityFrameworkCore
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
public override async Task SetApplicationIdAsync([NotNull] TAuthorization authorization, [CanBeNull] string identifier, CancellationToken cancellationToken)
public override async Task SetApplicationIdAsync([NotNull] TAuthorization authorization,
[CanBeNull] string identifier, CancellationToken cancellationToken)
{
if (authorization == null)
{

4
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs

@ -186,7 +186,7 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentNullException(nameof(query));
}
return query(Scopes, state).FirstOrDefaultAsync(cancellationToken);
return query(Scopes.AsTracking(), state).FirstOrDefaultAsync(cancellationToken);
}
/// <summary>
@ -210,7 +210,7 @@ namespace OpenIddict.EntityFrameworkCore
throw new ArgumentNullException(nameof(query));
}
return ImmutableArray.CreateRange(await query(Scopes, state).ToListAsync(cancellationToken));
return ImmutableArray.CreateRange(await query(Scopes.AsTracking(), state).ToListAsync(cancellationToken));
}
/// <summary>

22
src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs

@ -189,8 +189,8 @@ namespace OpenIddict.EntityFrameworkCore
// See https://github.com/openiddict/openiddict-core/issues/499 for more information.
IQueryable<TToken> Query(IQueryable<TApplication> applications, IQueryable<TToken> tokens, TKey key)
=> from token in tokens.Include(token => token.Application).Include(token => token.Authorization)
join application in applications on token.Application.Id equals application.Id
=> from token in tokens.Include(token => token.Application).Include(token => token.Authorization).AsTracking()
join application in applications.AsTracking() on token.Application.Id equals application.Id
where application.Id.Equals(key)
select token;
@ -220,8 +220,8 @@ namespace OpenIddict.EntityFrameworkCore
// See https://github.com/openiddict/openiddict-core/issues/499 for more information.
IQueryable<TToken> Query(IQueryable<TAuthorization> authorizations, IQueryable<TToken> tokens, TKey key)
=> from token in tokens.Include(token => token.Application).Include(token => token.Authorization)
join authorization in authorizations on token.Authorization.Id equals authorization.Id
=> from token in tokens.Include(token => token.Application).Include(token => token.Authorization).AsTracking()
join authorization in authorizations.AsTracking() on token.Authorization.Id equals authorization.Id
where authorization.Id.Equals(key)
select token;
@ -317,7 +317,8 @@ namespace OpenIddict.EntityFrameworkCore
return query(
Tokens.Include(token => token.Application)
.Include(token => token.Authorization), state).FirstOrDefaultAsync(cancellationToken);
.Include(token => token.Authorization)
.AsTracking(), state).FirstOrDefaultAsync(cancellationToken);
}
/// <summary>
@ -379,7 +380,8 @@ namespace OpenIddict.EntityFrameworkCore
return ImmutableArray.CreateRange(await query(
Tokens.Include(token => token.Application)
.Include(token => token.Authorization), state).ToListAsync(cancellationToken));
.Include(token => token.Authorization)
.AsTracking(), state).ToListAsync(cancellationToken));
}
/// <summary>
@ -398,7 +400,7 @@ namespace OpenIddict.EntityFrameworkCore
IList<Exception> exceptions = null;
IQueryable<TToken> Query(IQueryable<TToken> tokens, int offset)
=> (from token in tokens
=> (from token in tokens.AsTracking()
where token.ExpirationDate < DateTimeOffset.UtcNow ||
token.Status != OpenIddictConstants.Statuses.Valid
orderby token.Id
@ -481,7 +483,8 @@ namespace OpenIddict.EntityFrameworkCore
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
public override async Task SetApplicationIdAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken)
public override async Task SetApplicationIdAsync([NotNull] TToken token,
[CanBeNull] string identifier, CancellationToken cancellationToken)
{
if (token == null)
{
@ -526,7 +529,8 @@ namespace OpenIddict.EntityFrameworkCore
/// <returns>
/// A <see cref="Task"/> that can be used to monitor the asynchronous operation.
/// </returns>
public override async Task SetAuthorizationIdAsync([NotNull] TToken token, [CanBeNull] string identifier, CancellationToken cancellationToken)
public override async Task SetAuthorizationIdAsync([NotNull] TToken token,
[CanBeNull] string identifier, CancellationToken cancellationToken)
{
if (token == null)
{

Loading…
Cancel
Save