diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs index 3ce51bed..c0e62319 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs @@ -191,7 +191,8 @@ namespace OpenIddict.EntityFramework // Remove all the authorizations associated with the application and // the tokens attached to these implicit or explicit authorizations. - foreach (var authorization in await ListAuthorizationsAsync()) + var authorizations = await ListAuthorizationsAsync(); + foreach (var authorization in authorizations) { foreach (var token in authorization.Tokens) { @@ -202,7 +203,8 @@ namespace OpenIddict.EntityFramework } // Remove all the tokens associated with the application. - foreach (var token in await ListTokensAsync()) + var tokens = await ListTokensAsync(); + foreach (var token in tokens) { Tokens.Remove(token); } @@ -217,6 +219,19 @@ namespace OpenIddict.EntityFramework catch (DbUpdateConcurrencyException exception) { + // Reset the state of the entity to prevents future calls to SaveChangesAsync() from failing. + Context.Entry(application).State = EntityState.Unchanged; + + foreach (var authorization in authorizations) + { + Context.Entry(authorization).State = EntityState.Unchanged; + } + + foreach (var token in tokens) + { + Context.Entry(token).State = EntityState.Unchanged; + } + throw new OpenIddictExceptions.ConcurrencyException(new StringBuilder() .AppendLine("The application was concurrently updated and cannot be persisted in its current state.") .Append("Reload the application from the database and retry the operation.") @@ -988,6 +1003,9 @@ namespace OpenIddict.EntityFramework catch (DbUpdateConcurrencyException exception) { + // Reset the state of the entity to prevents future calls to SaveChangesAsync() from failing. + Context.Entry(application).State = EntityState.Unchanged; + throw new OpenIddictExceptions.ConcurrencyException(new StringBuilder() .AppendLine("The application was concurrently updated and cannot be persisted in its current state.") .Append("Reload the application from the database and retry the operation.") diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs index c0908422..81d3122d 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs @@ -184,7 +184,8 @@ namespace OpenIddict.EntityFramework using (var transaction = CreateTransaction()) { // Remove all the tokens associated with the authorization. - foreach (var token in await ListTokensAsync()) + var tokens = await ListTokensAsync(); + foreach (var token in tokens) { Tokens.Remove(token); } @@ -199,6 +200,14 @@ namespace OpenIddict.EntityFramework catch (DbUpdateConcurrencyException exception) { + // Reset the state of the entity to prevents future calls to SaveChangesAsync() from failing. + Context.Entry(authorization).State = EntityState.Unchanged; + + foreach (var token in tokens) + { + Context.Entry(token).State = EntityState.Unchanged; + } + throw new OpenIddictExceptions.ConcurrencyException(new StringBuilder() .AppendLine("The authorization was concurrently updated and cannot be persisted in its current state.") .Append("Reload the authorization from the database and retry the operation.") @@ -971,6 +980,9 @@ namespace OpenIddict.EntityFramework catch (DbUpdateConcurrencyException exception) { + // Reset the state of the entity to prevents future calls to SaveChangesAsync() from failing. + Context.Entry(authorization).State = EntityState.Unchanged; + throw new OpenIddictExceptions.ConcurrencyException(new StringBuilder() .AppendLine("The authorization was concurrently updated and cannot be persisted in its current state.") .Append("Reload the authorization from the database and retry the operation.") diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs index cff96c40..b58fc75a 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs @@ -152,6 +152,9 @@ namespace OpenIddict.EntityFramework catch (DbUpdateConcurrencyException exception) { + // Reset the state of the entity to prevents future calls to SaveChangesAsync() from failing. + Context.Entry(scope).State = EntityState.Unchanged; + throw new OpenIddictExceptions.ConcurrencyException(new StringBuilder() .AppendLine("The scope was concurrently updated and cannot be persisted in its current state.") .Append("Reload the scope from the database and retry the operation.") @@ -636,6 +639,9 @@ namespace OpenIddict.EntityFramework catch (DbUpdateConcurrencyException exception) { + // Reset the state of the entity to prevents future calls to SaveChangesAsync() from failing. + Context.Entry(scope).State = EntityState.Unchanged; + throw new OpenIddictExceptions.ConcurrencyException(new StringBuilder() .AppendLine("The scope was concurrently updated and cannot be persisted in its current state.") .Append("Reload the scope from the database and retry the operation.") diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs index 69735ef9..f05efdba 100644 --- a/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs +++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs @@ -169,6 +169,9 @@ namespace OpenIddict.EntityFramework catch (DbUpdateConcurrencyException exception) { + // Reset the state of the entity to prevents future calls to SaveChangesAsync() from failing. + Context.Entry(token).State = EntityState.Unchanged; + throw new OpenIddictExceptions.ConcurrencyException(new StringBuilder() .AppendLine("The token was concurrently updated and cannot be persisted in its current state.") .Append("Reload the token from the database and retry the operation.") @@ -1117,6 +1120,9 @@ namespace OpenIddict.EntityFramework catch (DbUpdateConcurrencyException exception) { + // Reset the state of the entity to prevents future calls to SaveChangesAsync() from failing. + Context.Entry(token).State = EntityState.Unchanged; + throw new OpenIddictExceptions.ConcurrencyException(new StringBuilder() .AppendLine("The token was concurrently updated and cannot be persisted in its current state.") .Append("Reload the token from the database and retry the operation.") diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs index 773dfe27..b2996ac6 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs @@ -234,7 +234,8 @@ namespace OpenIddict.EntityFrameworkCore // Remove all the authorizations associated with the application and // the tokens attached to these implicit or explicit authorizations. - foreach (var authorization in await ListAuthorizationsAsync()) + var authorizations = await ListAuthorizationsAsync(); + foreach (var authorization in authorizations) { foreach (var token in authorization.Tokens) { @@ -245,7 +246,8 @@ namespace OpenIddict.EntityFrameworkCore } // Remove all the tokens associated with the application. - foreach (var token in await ListTokensAsync()) + var tokens = await ListTokensAsync(); + foreach (var token in tokens) { Context.Remove(token); } @@ -260,6 +262,19 @@ namespace OpenIddict.EntityFrameworkCore catch (DbUpdateConcurrencyException exception) { + // Reset the state of the entity to prevents future calls to SaveChangesAsync() from failing. + Context.Entry(application).State = EntityState.Unchanged; + + foreach (var authorization in authorizations) + { + Context.Entry(authorization).State = EntityState.Unchanged; + } + + foreach (var token in tokens) + { + Context.Entry(token).State = EntityState.Unchanged; + } + throw new OpenIddictExceptions.ConcurrencyException(new StringBuilder() .AppendLine("The application was concurrently updated and cannot be persisted in its current state.") .Append("Reload the application from the database and retry the operation.") @@ -1035,6 +1050,9 @@ namespace OpenIddict.EntityFrameworkCore catch (DbUpdateConcurrencyException exception) { + // Reset the state of the entity to prevents future calls to SaveChangesAsync() from failing. + Context.Entry(application).State = EntityState.Unchanged; + throw new OpenIddictExceptions.ConcurrencyException(new StringBuilder() .AppendLine("The application was concurrently updated and cannot be persisted in its current state.") .Append("Reload the application from the database and retry the operation.") diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs index bf46a016..bbe00c50 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs @@ -221,7 +221,8 @@ namespace OpenIddict.EntityFrameworkCore using var transaction = await CreateTransactionAsync(); // Remove all the tokens associated with the authorization. - foreach (var token in await ListTokensAsync()) + var tokens = await ListTokensAsync(); + foreach (var token in tokens) { Context.Remove(token); } @@ -236,6 +237,14 @@ namespace OpenIddict.EntityFrameworkCore catch (DbUpdateConcurrencyException exception) { + // Reset the state of the entity to prevents future calls to SaveChangesAsync() from failing. + Context.Entry(authorization).State = EntityState.Unchanged; + + foreach (var token in tokens) + { + Context.Entry(token).State = EntityState.Unchanged; + } + throw new OpenIddictExceptions.ConcurrencyException(new StringBuilder() .AppendLine("The authorization was concurrently updated and cannot be persisted in its current state.") .Append("Reload the authorization from the database and retry the operation.") @@ -1029,6 +1038,9 @@ namespace OpenIddict.EntityFrameworkCore catch (DbUpdateConcurrencyException exception) { + // Reset the state of the entity to prevents future calls to SaveChangesAsync() from failing. + Context.Entry(authorization).State = EntityState.Unchanged; + throw new OpenIddictExceptions.ConcurrencyException(new StringBuilder() .AppendLine("The authorization was concurrently updated and cannot be persisted in its current state.") .Append("Reload the authorization from the database and retry the operation.") diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs index 69699c2d..1489511a 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs @@ -169,6 +169,9 @@ namespace OpenIddict.EntityFrameworkCore catch (DbUpdateConcurrencyException exception) { + // Reset the state of the entity to prevents future calls to SaveChangesAsync() from failing. + Context.Entry(scope).State = EntityState.Unchanged; + throw new OpenIddictExceptions.ConcurrencyException(new StringBuilder() .AppendLine("The scope was concurrently updated and cannot be persisted in its current state.") .Append("Reload the scope from the database and retry the operation.") @@ -651,6 +654,9 @@ namespace OpenIddict.EntityFrameworkCore catch (DbUpdateConcurrencyException exception) { + // Reset the state of the entity to prevents future calls to SaveChangesAsync() from failing. + Context.Entry(scope).State = EntityState.Unchanged; + throw new OpenIddictExceptions.ConcurrencyException(new StringBuilder() .AppendLine("The scope was concurrently updated and cannot be persisted in its current state.") .Append("Reload the scope from the database and retry the operation.") diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs index 067101fa..12c10f13 100644 --- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs +++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs @@ -190,6 +190,9 @@ namespace OpenIddict.EntityFrameworkCore catch (DbUpdateConcurrencyException exception) { + // Reset the state of the entity to prevents future calls to SaveChangesAsync() from failing. + Context.Entry(token).State = EntityState.Unchanged; + throw new OpenIddictExceptions.ConcurrencyException(new StringBuilder() .AppendLine("The token was concurrently updated and cannot be persisted in its current state.") .Append("Reload the token from the database and retry the operation.") @@ -1209,6 +1212,9 @@ namespace OpenIddict.EntityFrameworkCore catch (DbUpdateConcurrencyException exception) { + // Reset the state of the entity to prevents future calls to SaveChangesAsync() from failing. + Context.Entry(token).State = EntityState.Unchanged; + throw new OpenIddictExceptions.ConcurrencyException(new StringBuilder() .AppendLine("The token was concurrently updated and cannot be persisted in its current state.") .Append("Reload the token from the database and retry the operation.")