diff --git a/src/OpenIddict.Core/Descriptors/OpenIddictScopeDescriptor.cs b/src/OpenIddict.Core/Descriptors/OpenIddictScopeDescriptor.cs
new file mode 100644
index 00000000..edcc69d4
--- /dev/null
+++ b/src/OpenIddict.Core/Descriptors/OpenIddictScopeDescriptor.cs
@@ -0,0 +1,14 @@
+namespace OpenIddict.Core
+{
+ ///
+ /// Represents an OpenIddict scope descriptor.
+ ///
+ public class OpenIddictScopeDescriptor
+ {
+ ///
+ /// Gets or sets the unique name
+ /// associated with the scope.
+ ///
+ public virtual string Name { get; set; }
+ }
+}
diff --git a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
index 8a510128..60f8c59a 100644
--- a/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
+++ b/src/OpenIddict.Core/Managers/OpenIddictApplicationManager.cs
@@ -38,6 +38,39 @@ namespace OpenIddict.Core
///
protected IOpenIddictApplicationStore Store { get; }
+ ///
+ /// Determines the number of applications that exist in the database.
+ ///
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of applications in the database.
+ ///
+ public virtual Task CountAsync(CancellationToken cancellationToken)
+ {
+ return Store.CountAsync(cancellationToken);
+ }
+
+ ///
+ /// Determines the number of applications that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of applications that match the specified query.
+ ///
+ public virtual Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return Store.CountAsync(query, cancellationToken);
+ }
+
///
/// Creates a new application.
///
@@ -428,6 +461,21 @@ namespace OpenIddict.Core
return string.Equals(type, OpenIddictConstants.ClientTypes.Public, StringComparison.OrdinalIgnoreCase);
}
+ ///
+ /// Executes the specified query.
+ ///
+ /// The number of results to return.
+ /// The number of results to skip.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ public virtual Task ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
+ {
+ return Store.ListAsync(count, offset, cancellationToken);
+ }
+
///
/// Executes the specified query.
///
diff --git a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
index 284d7ba4..945e1614 100644
--- a/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
+++ b/src/OpenIddict.Core/Managers/OpenIddictAuthorizationManager.cs
@@ -37,6 +37,39 @@ namespace OpenIddict.Core
///
protected IOpenIddictAuthorizationStore Store { get; }
+ ///
+ /// Determines the number of authorizations that exist in the database.
+ ///
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of authorizations in the database.
+ ///
+ public virtual Task CountAsync(CancellationToken cancellationToken)
+ {
+ return Store.CountAsync(cancellationToken);
+ }
+
+ ///
+ /// Determines the number of authorizations that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of authorizations that match the specified query.
+ ///
+ public virtual Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return Store.CountAsync(query, cancellationToken);
+ }
+
///
/// Creates a new authorization.
///
@@ -75,6 +108,24 @@ namespace OpenIddict.Core
return await Store.CreateAsync(descriptor, cancellationToken);
}
+ ///
+ /// Removes an existing authorization.
+ ///
+ /// The authorization to delete.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public virtual Task DeleteAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
+ {
+ if (authorization == null)
+ {
+ throw new ArgumentNullException(nameof(authorization));
+ }
+
+ return Store.DeleteAsync(authorization, cancellationToken);
+ }
+
///
/// Retrieves an authorization using its associated subject/client.
///
@@ -143,6 +194,21 @@ namespace OpenIddict.Core
return Store.GetIdAsync(authorization, cancellationToken);
}
+ ///
+ /// Executes the specified query.
+ ///
+ /// The number of results to return.
+ /// The number of results to skip.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ public virtual Task ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
+ {
+ return Store.ListAsync(count, offset, cancellationToken);
+ }
+
///
/// Executes the specified query.
///
diff --git a/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs b/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs
index 10448be4..92f6655e 100644
--- a/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs
+++ b/src/OpenIddict.Core/Managers/OpenIddictScopeManager.cs
@@ -37,6 +37,93 @@ namespace OpenIddict.Core
///
protected IOpenIddictScopeStore Store { get; }
+ ///
+ /// Determines the number of scopes that exist in the database.
+ ///
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of scopes in the database.
+ ///
+ public virtual Task CountAsync(CancellationToken cancellationToken)
+ {
+ return Store.CountAsync(cancellationToken);
+ }
+
+ ///
+ /// Determines the number of scopes that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of scopes that match the specified query.
+ ///
+ public virtual Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return Store.CountAsync(query, cancellationToken);
+ }
+
+ ///
+ /// Creates a new scope.
+ ///
+ /// The scope to create.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result returns the scope.
+ ///
+ public virtual Task CreateAsync([NotNull] TScope scope, CancellationToken cancellationToken)
+ {
+ if (scope == null)
+ {
+ throw new ArgumentNullException(nameof(scope));
+ }
+
+ return Store.CreateAsync(scope, cancellationToken);
+ }
+
+ ///
+ /// Creates a new scope.
+ ///
+ /// The scope descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result returns the scope.
+ ///
+ public virtual Task CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken)
+ {
+ if (descriptor == null)
+ {
+ throw new ArgumentNullException(nameof(descriptor));
+ }
+
+ return Store.CreateAsync(descriptor, cancellationToken);
+ }
+
+ ///
+ /// Removes an existing scope.
+ ///
+ /// The scope to delete.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public virtual Task DeleteAsync([NotNull] TScope scope, CancellationToken cancellationToken)
+ {
+ if (scope == null)
+ {
+ throw new ArgumentNullException(nameof(scope));
+ }
+
+ return Store.DeleteAsync(scope, cancellationToken);
+ }
+
///
/// Executes the specified query.
///
@@ -57,6 +144,21 @@ namespace OpenIddict.Core
return Store.GetAsync(query, cancellationToken);
}
+ ///
+ /// Executes the specified query.
+ ///
+ /// The number of results to return.
+ /// The number of results to skip.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ public virtual Task ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
+ {
+ return Store.ListAsync(count, offset, cancellationToken);
+ }
+
///
/// Executes the specified query.
///
@@ -76,5 +178,23 @@ namespace OpenIddict.Core
return Store.ListAsync(query, cancellationToken);
}
+
+ ///
+ /// Updates an existing scope.
+ ///
+ /// The scope to update.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public virtual Task UpdateAsync([NotNull] TScope scope, CancellationToken cancellationToken)
+ {
+ if (scope == null)
+ {
+ throw new ArgumentNullException(nameof(scope));
+ }
+
+ return Store.UpdateAsync(scope, cancellationToken);
+ }
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs
index f6bdb666..4e1a7dc4 100644
--- a/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs
+++ b/src/OpenIddict.Core/Managers/OpenIddictTokenManager.cs
@@ -38,6 +38,39 @@ namespace OpenIddict.Core
///
protected IOpenIddictTokenStore Store { get; }
+ ///
+ /// Determines the number of tokens that exist in the database.
+ ///
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of tokens in the database.
+ ///
+ public virtual Task CountAsync(CancellationToken cancellationToken)
+ {
+ return Store.CountAsync(cancellationToken);
+ }
+
+ ///
+ /// Determines the number of tokens that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of tokens that match the specified query.
+ ///
+ public virtual Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return Store.CountAsync(query, cancellationToken);
+ }
+
///
/// Creates a new token.
///
@@ -371,6 +404,21 @@ namespace OpenIddict.Core
return string.Equals(status, OpenIddictConstants.Statuses.Valid, StringComparison.OrdinalIgnoreCase);
}
+ ///
+ /// Executes the specified query.
+ ///
+ /// The number of results to return.
+ /// The number of results to skip.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ public virtual Task ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
+ {
+ return Store.ListAsync(count, offset, cancellationToken);
+ }
+
///
/// Executes the specified query.
///
diff --git a/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs
index 76de9dbe..2b22f014 100644
--- a/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs
+++ b/src/OpenIddict.Core/Stores/IOpenIddictApplicationStore.cs
@@ -19,6 +19,28 @@ namespace OpenIddict.Core
/// The type of the Application entity.
public interface IOpenIddictApplicationStore where TApplication : class
{
+ ///
+ /// Determines the number of applications that exist in the database.
+ ///
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of applications in the database.
+ ///
+ Task CountAsync(CancellationToken cancellationToken);
+
+ ///
+ /// Determines the number of applications that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of applications that match the specified query.
+ ///
+ Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
///
/// Creates a new application.
///
@@ -195,6 +217,18 @@ namespace OpenIddict.Core
///
Task GetTokensAsync([NotNull] TApplication application, CancellationToken cancellationToken);
+ ///
+ /// Executes the specified query.
+ ///
+ /// The number of results to return.
+ /// The number of results to skip.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ Task ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken);
+
///
/// Executes the specified query.
///
diff --git a/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs
index 44b6b506..1449c97f 100644
--- a/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs
+++ b/src/OpenIddict.Core/Stores/IOpenIddictAuthorizationStore.cs
@@ -18,6 +18,28 @@ namespace OpenIddict.Core
/// The type of the Authorization entity.
public interface IOpenIddictAuthorizationStore where TAuthorization : class
{
+ ///
+ /// Determines the number of authorizations that exist in the database.
+ ///
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of authorizations in the database.
+ ///
+ Task CountAsync(CancellationToken cancellationToken);
+
+ ///
+ /// Determines the number of authorizations that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of authorizations that match the specified query.
+ ///
+ Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
///
/// Creates a new authorization.
///
@@ -38,6 +60,16 @@ namespace OpenIddict.Core
///
Task CreateAsync([NotNull] OpenIddictAuthorizationDescriptor descriptor, CancellationToken cancellationToken);
+ ///
+ /// Removes an existing authorization.
+ ///
+ /// The authorization to delete.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ Task DeleteAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken);
+
///
/// Retrieves an authorization using its associated subject/client.
///
@@ -106,6 +138,18 @@ namespace OpenIddict.Core
///
Task GetSubjectAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken);
+ ///
+ /// Executes the specified query.
+ ///
+ /// The number of results to return.
+ /// The number of results to skip.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ Task ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken);
+
///
/// Executes the specified query.
///
diff --git a/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs
index d1d59ebe..dfff703a 100644
--- a/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs
+++ b/src/OpenIddict.Core/Stores/IOpenIddictScopeStore.cs
@@ -18,6 +18,58 @@ namespace OpenIddict.Core
/// The type of the Scope entity.
public interface IOpenIddictScopeStore where TScope : class
{
+ ///
+ /// Determines the number of scopes that exist in the database.
+ ///
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of scopes in the database.
+ ///
+ Task CountAsync(CancellationToken cancellationToken);
+
+ ///
+ /// Determines the number of scopes that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of scopes that match the specified query.
+ ///
+ Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
+ ///
+ /// Creates a new scope.
+ ///
+ /// The scope to create.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result returns the scope.
+ ///
+ Task CreateAsync([NotNull] TScope scope, CancellationToken cancellationToken);
+
+ ///
+ /// Creates a new scope.
+ ///
+ /// The scope descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result returns the scope.
+ ///
+ Task CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken);
+
+ ///
+ /// Removes an existing scope.
+ ///
+ /// The scope to delete.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ Task DeleteAsync([NotNull] TScope scope, CancellationToken cancellationToken);
+
///
/// Executes the specified query.
///
@@ -30,6 +82,18 @@ namespace OpenIddict.Core
///
Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+ ///
+ /// Executes the specified query.
+ ///
+ /// The number of results to return.
+ /// The number of results to skip.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ Task ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken);
+
///
/// Executes the specified query.
///
@@ -41,5 +105,15 @@ namespace OpenIddict.Core
/// whose result returns all the elements returned when executing the specified query.
///
Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
+ ///
+ /// Updates an existing scope.
+ ///
+ /// The scope to update.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ Task UpdateAsync([NotNull] TScope scope, CancellationToken cancellationToken);
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs b/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs
index db25f7e5..63386493 100644
--- a/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs
+++ b/src/OpenIddict.Core/Stores/IOpenIddictTokenStore.cs
@@ -18,6 +18,28 @@ namespace OpenIddict.Core
/// The type of the Token entity.
public interface IOpenIddictTokenStore where TToken : class
{
+ ///
+ /// Determines the number of tokens that exist in the database.
+ ///
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of applications in the database.
+ ///
+ Task CountAsync(CancellationToken cancellationToken);
+
+ ///
+ /// Determines the number of tokens that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of tokens that match the specified query.
+ ///
+ Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
///
/// Creates a new token.
///
@@ -29,7 +51,7 @@ namespace OpenIddict.Core
Task CreateAsync([NotNull] TToken token, CancellationToken cancellationToken);
///
- /// Creates a new token, which is associated with a particular subject.
+ /// Creates a new token.
///
/// The token descriptor.
/// The that can be used to abort the operation.
@@ -201,6 +223,18 @@ namespace OpenIddict.Core
///
Task GetTokenTypeAsync([NotNull] TToken token, CancellationToken cancellationToken);
+ ///
+ /// Executes the specified query.
+ ///
+ /// The number of results to return.
+ /// The number of results to skip.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ Task ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken);
+
///
/// Executes the specified query.
///
diff --git a/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs
index bec50e1f..51b80ddc 100644
--- a/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs
+++ b/src/OpenIddict.Core/Stores/OpenIddictApplicationStore.cs
@@ -30,6 +30,31 @@ namespace OpenIddict.Core
where TToken : OpenIddictToken, new()
where TKey : IEquatable
{
+ ///
+ /// Determines the number of applications that exist in the database.
+ ///
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of applications in the database.
+ ///
+ public virtual Task CountAsync(CancellationToken cancellationToken)
+ {
+ return CountAsync(applications => applications, cancellationToken);
+ }
+
+ ///
+ /// Determines the number of applications that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of applications that match the specified query.
+ ///
+ public abstract Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
///
/// Creates a new application.
///
@@ -421,6 +446,38 @@ namespace OpenIddict.Core
return tokens.ToArray();
}
+ ///
+ /// Executes the specified query.
+ ///
+ /// The number of results to return.
+ /// The number of results to skip.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ public virtual Task ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
+ {
+ IQueryable Query(IQueryable applications)
+ {
+ var query = applications.OrderBy(application => application.Id).AsQueryable();
+
+ if (offset.HasValue)
+ {
+ query = query.Skip(offset.Value);
+ }
+
+ if (count.HasValue)
+ {
+ query = query.Take(count.Value);
+ }
+
+ return query;
+ }
+
+ return ListAsync(Query, cancellationToken);
+ }
+
///
/// Executes the specified query.
///
diff --git a/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs
index 75a1bc80..5af2732f 100644
--- a/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs
+++ b/src/OpenIddict.Core/Stores/OpenIddictAuthorizationStore.cs
@@ -28,6 +28,31 @@ namespace OpenIddict.Core
where TToken : OpenIddictToken, new()
where TKey : IEquatable
{
+ ///
+ /// Determines the number of authorizations that exist in the database.
+ ///
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of authorizations in the database.
+ ///
+ public virtual Task CountAsync(CancellationToken cancellationToken)
+ {
+ return CountAsync(authorizations => authorizations, cancellationToken);
+ }
+
+ ///
+ /// Determines the number of authorizations that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of authorizations that match the specified query.
+ ///
+ public abstract Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
///
/// Creates a new authorization.
///
@@ -48,6 +73,16 @@ namespace OpenIddict.Core
///
public abstract Task CreateAsync([NotNull] OpenIddictAuthorizationDescriptor descriptor, CancellationToken cancellationToken);
+ ///
+ /// Removes an existing authorization.
+ ///
+ /// The authorization to delete.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public abstract Task DeleteAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken);
+
///
/// Retrieves an authorization using its associated subject/client.
///
@@ -164,6 +199,38 @@ namespace OpenIddict.Core
return Task.FromResult(authorization.Subject);
}
+ ///
+ /// Executes the specified query.
+ ///
+ /// The number of results to return.
+ /// The number of results to skip.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ public virtual Task ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
+ {
+ IQueryable Query(IQueryable authorizations)
+ {
+ var query = authorizations.OrderBy(authorization => authorization.Id).AsQueryable();
+
+ if (offset.HasValue)
+ {
+ query = query.Skip(offset.Value);
+ }
+
+ if (count.HasValue)
+ {
+ query = query.Take(count.Value);
+ }
+
+ return query;
+ }
+
+ return ListAsync(Query, cancellationToken);
+ }
+
///
/// Executes the specified query.
///
diff --git a/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs
index 22c4520f..f51755b2 100644
--- a/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs
+++ b/src/OpenIddict.Core/Stores/OpenIddictScopeStore.cs
@@ -24,6 +24,61 @@ namespace OpenIddict.Core
where TScope : OpenIddictScope, new()
where TKey : IEquatable
{
+ ///
+ /// Determines the number of scopes that exist in the database.
+ ///
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of scopes in the database.
+ ///
+ public virtual Task CountAsync(CancellationToken cancellationToken)
+ {
+ return CountAsync(scopes => scopes, cancellationToken);
+ }
+
+ ///
+ /// Determines the number of scopes that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of scopes that match the specified query.
+ ///
+ public abstract Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
+ ///
+ /// Creates a new scope.
+ ///
+ /// The scope to create.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result returns the scope.
+ ///
+ public abstract Task CreateAsync([NotNull] TScope scope, CancellationToken cancellationToken);
+
+ ///
+ /// Creates a new scope.
+ ///
+ /// The scope descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result returns the scope.
+ ///
+ public abstract Task CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken);
+
+ ///
+ /// Removes an existing scope.
+ ///
+ /// The scope to delete.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public abstract Task DeleteAsync([NotNull] TScope scope, CancellationToken cancellationToken);
+
///
/// Executes the specified query.
///
@@ -36,6 +91,38 @@ namespace OpenIddict.Core
///
public abstract Task GetAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+ ///
+ /// Executes the specified query.
+ ///
+ /// The number of results to return.
+ /// The number of results to skip.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ public virtual Task ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
+ {
+ IQueryable Query(IQueryable scopes)
+ {
+ var query = scopes.OrderBy(scope => scope.Id).AsQueryable();
+
+ if (offset.HasValue)
+ {
+ query = query.Skip(offset.Value);
+ }
+
+ if (count.HasValue)
+ {
+ query = query.Take(count.Value);
+ }
+
+ return query;
+ }
+
+ return ListAsync(Query, cancellationToken);
+ }
+
///
/// Executes the specified query.
///
@@ -48,6 +135,16 @@ namespace OpenIddict.Core
///
public abstract Task ListAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+ ///
+ /// Updates an existing scope.
+ ///
+ /// The scope to update.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public abstract Task UpdateAsync([NotNull] TScope scope, CancellationToken cancellationToken);
+
///
/// Converts the provided identifier to a strongly typed key object.
///
diff --git a/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs
index d98fafdf..a5f7aea5 100644
--- a/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs
+++ b/src/OpenIddict.Core/Stores/OpenIddictTokenStore.cs
@@ -28,6 +28,31 @@ namespace OpenIddict.Core
where TAuthorization : OpenIddictAuthorization, new()
where TKey : IEquatable
{
+ ///
+ /// Determines the number of tokens that exist in the database.
+ ///
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of applications in the database.
+ ///
+ public virtual Task CountAsync(CancellationToken cancellationToken)
+ {
+ return CountAsync(tokens => tokens, cancellationToken);
+ }
+
+ ///
+ /// Determines the number of tokens that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of tokens that match the specified query.
+ ///
+ public abstract Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken);
+
///
/// Creates a new token.
///
@@ -39,7 +64,7 @@ namespace OpenIddict.Core
public abstract Task CreateAsync([NotNull] TToken token, CancellationToken cancellationToken);
///
- /// Creates a new token, which is associated with a particular subject.
+ /// Creates a new token.
///
/// The token descriptor.
/// The that can be used to abort the operation.
@@ -329,6 +354,38 @@ namespace OpenIddict.Core
return Task.FromResult(token.Type);
}
+ ///
+ /// Executes the specified query.
+ ///
+ /// The number of results to return.
+ /// The number of results to skip.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns all the elements returned when executing the specified query.
+ ///
+ public virtual Task ListAsync([CanBeNull] int? count, [CanBeNull] int? offset, CancellationToken cancellationToken)
+ {
+ IQueryable Query(IQueryable tokens)
+ {
+ var query = tokens.OrderBy(token => token.Id).AsQueryable();
+
+ if (offset.HasValue)
+ {
+ query = query.Skip(offset.Value);
+ }
+
+ if (count.HasValue)
+ {
+ query = query.Take(count.Value);
+ }
+
+ return query;
+ }
+
+ return ListAsync(Query, cancellationToken);
+ }
+
///
/// Executes the specified query.
///
diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs
index 52cc69b4..16fac810 100644
--- a/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs
+++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictApplicationStore.cs
@@ -81,6 +81,26 @@ namespace OpenIddict.EntityFramework
///
protected DbSet Applications => Context.Set();
+ ///
+ /// Determines the number of applications that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of applications that match the specified query.
+ ///
+ public override Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return query.Invoke(Applications).LongCountAsync();
+ }
+
///
/// Creates a new application.
///
diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs
index 217bfeed..f880d828 100644
--- a/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs
+++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictAuthorizationStore.cs
@@ -86,6 +86,26 @@ namespace OpenIddict.EntityFramework
///
protected DbSet Authorizations => Context.Set();
+ ///
+ /// Determines the number of authorizations that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of authorizations that match the specified query.
+ ///
+ public override Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return query.Invoke(Authorizations).LongCountAsync();
+ }
+
///
/// Creates a new authorization.
///
@@ -149,6 +169,31 @@ namespace OpenIddict.EntityFramework
return await CreateAsync(authorization, cancellationToken);
}
+ ///
+ /// Removes an existing authorization.
+ ///
+ /// The authorization to delete.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public override async Task DeleteAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
+ {
+ if (authorization == null)
+ {
+ throw new ArgumentNullException(nameof(authorization));
+ }
+
+ Authorizations.Remove(authorization);
+
+ try
+ {
+ await Context.SaveChangesAsync(cancellationToken);
+ }
+
+ catch (DbUpdateConcurrencyException) { }
+ }
+
///
/// Retrieves an authorization using its unique identifier.
///
diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs
index b960fba4..bebf6409 100644
--- a/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs
+++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictScopeStore.cs
@@ -6,10 +6,12 @@
using System;
using System.Data.Entity;
+using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
+using OpenIddict.Core;
using OpenIddict.Models;
namespace OpenIddict.EntityFramework
@@ -70,6 +72,91 @@ namespace OpenIddict.EntityFramework
///
protected DbSet Scopes => Context.Set();
+ ///
+ /// Determines the number of scopes that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of scopes that match the specified query.
+ ///
+ public override Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return query.Invoke(Scopes).LongCountAsync();
+ }
+
+ ///
+ /// Creates a new scope.
+ ///
+ /// The scope to create.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result returns the scope.
+ ///
+ public override async Task CreateAsync([NotNull] TScope scope, CancellationToken cancellationToken)
+ {
+ if (scope == null)
+ {
+ throw new ArgumentNullException(nameof(scope));
+ }
+
+ Scopes.Add(scope);
+
+ await Context.SaveChangesAsync(cancellationToken);
+
+ return scope;
+ }
+
+ ///
+ /// Creates a new scope.
+ ///
+ /// The scope descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result returns the scope.
+ ///
+ public override Task CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken)
+ {
+ var scope = new TScope
+ {
+ Name = descriptor.Name
+ };
+
+ return CreateAsync(scope, cancellationToken);
+ }
+
+ ///
+ /// Removes an existing scope.
+ ///
+ /// The scope to delete.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public override async Task DeleteAsync([NotNull] TScope scope, CancellationToken cancellationToken)
+ {
+ if (scope == null)
+ {
+ throw new ArgumentNullException(nameof(scope));
+ }
+
+ Scopes.Remove(scope);
+
+ try
+ {
+ await Context.SaveChangesAsync(cancellationToken);
+ }
+
+ catch (DbUpdateConcurrencyException) { }
+ }
+
///
/// Executes the specified query.
///
@@ -109,5 +196,31 @@ namespace OpenIddict.EntityFramework
return query.Invoke(Scopes).ToArrayAsync(cancellationToken);
}
+
+ ///
+ /// Updates an existing scope.
+ ///
+ /// The scope to update.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public override async Task UpdateAsync([NotNull] TScope scope, CancellationToken cancellationToken)
+ {
+ if (scope == null)
+ {
+ throw new ArgumentNullException(nameof(scope));
+ }
+
+ Scopes.Attach(scope);
+ Context.Entry(scope).State = EntityState.Modified;
+
+ try
+ {
+ await Context.SaveChangesAsync(cancellationToken);
+ }
+
+ catch (DbUpdateConcurrencyException) { }
+ }
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs
index 1987e46e..3d8c85c5 100644
--- a/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs
+++ b/src/OpenIddict.EntityFramework/Stores/OpenIddictTokenStore.cs
@@ -91,6 +91,26 @@ namespace OpenIddict.EntityFramework
///
protected DbSet Tokens => Context.Set();
+ ///
+ /// Determines the number of tokens that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of tokens that match the specified query.
+ ///
+ public override Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return query.Invoke(Tokens).LongCountAsync();
+ }
+
///
/// Creates a new token.
///
@@ -114,7 +134,7 @@ namespace OpenIddict.EntityFramework
}
///
- /// Creates a new token, which is associated with a particular subject.
+ /// Creates a new token.
///
/// The token descriptor.
/// The that can be used to abort the operation.
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs
index d2ebeaf3..750b3de8 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictApplicationStore.cs
@@ -80,6 +80,26 @@ namespace OpenIddict.EntityFrameworkCore
///
protected DbSet Applications => Context.Set();
+ ///
+ /// Determines the number of applications that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of applications that match the specified query.
+ ///
+ public override Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return query.Invoke(Applications).LongCountAsync();
+ }
+
///
/// Creates a new application.
///
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs
index 35351fa2..df97afd9 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictAuthorizationStore.cs
@@ -85,6 +85,26 @@ namespace OpenIddict.EntityFrameworkCore
///
protected DbSet Authorizations => Context.Set();
+ ///
+ /// Determines the number of authorizations that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of authorizations that match the specified query.
+ ///
+ public override Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return query.Invoke(Authorizations).LongCountAsync();
+ }
+
///
/// Creates a new authorization.
///
@@ -148,6 +168,31 @@ namespace OpenIddict.EntityFrameworkCore
return await CreateAsync(authorization, cancellationToken);
}
+ ///
+ /// Removes an existing authorization.
+ ///
+ /// The authorization to delete.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public override async Task DeleteAsync([NotNull] TAuthorization authorization, CancellationToken cancellationToken)
+ {
+ if (authorization == null)
+ {
+ throw new ArgumentNullException(nameof(authorization));
+ }
+
+ Context.Remove(authorization);
+
+ try
+ {
+ await Context.SaveChangesAsync(cancellationToken);
+ }
+
+ catch (DbUpdateConcurrencyException) { }
+ }
+
///
/// Retrieves an authorization using its unique identifier.
///
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs
index ccd0b49f..05429eaa 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictScopeStore.cs
@@ -10,6 +10,7 @@ using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore;
+using OpenIddict.Core;
using OpenIddict.Models;
namespace OpenIddict.EntityFrameworkCore
@@ -70,6 +71,91 @@ namespace OpenIddict.EntityFrameworkCore
///
protected DbSet Scopes => Context.Set();
+ ///
+ /// Determines the number of scopes that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of scopes that match the specified query.
+ ///
+ public override Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return query.Invoke(Scopes).LongCountAsync();
+ }
+
+ ///
+ /// Creates a new scope.
+ ///
+ /// The scope to create.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result returns the scope.
+ ///
+ public override async Task CreateAsync([NotNull] TScope scope, CancellationToken cancellationToken)
+ {
+ if (scope == null)
+ {
+ throw new ArgumentNullException(nameof(scope));
+ }
+
+ Scopes.Add(scope);
+
+ await Context.SaveChangesAsync(cancellationToken);
+
+ return scope;
+ }
+
+ ///
+ /// Creates a new scope.
+ ///
+ /// The scope descriptor.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation, whose result returns the scope.
+ ///
+ public override Task CreateAsync([NotNull] OpenIddictScopeDescriptor descriptor, CancellationToken cancellationToken)
+ {
+ var scope = new TScope
+ {
+ Name = descriptor.Name
+ };
+
+ return CreateAsync(scope, cancellationToken);
+ }
+
+ ///
+ /// Removes an existing scope.
+ ///
+ /// The scope to delete.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public override async Task DeleteAsync([NotNull] TScope scope, CancellationToken cancellationToken)
+ {
+ if (scope == null)
+ {
+ throw new ArgumentNullException(nameof(scope));
+ }
+
+ Context.Remove(scope);
+
+ try
+ {
+ await Context.SaveChangesAsync(cancellationToken);
+ }
+
+ catch (DbUpdateConcurrencyException) { }
+ }
+
///
/// Executes the specified query.
///
@@ -109,5 +195,31 @@ namespace OpenIddict.EntityFrameworkCore
return query.Invoke(Scopes).ToArrayAsync(cancellationToken);
}
+
+ ///
+ /// Updates an existing scope.
+ ///
+ /// The scope to update.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation.
+ ///
+ public override async Task UpdateAsync([NotNull] TScope scope, CancellationToken cancellationToken)
+ {
+ if (scope == null)
+ {
+ throw new ArgumentNullException(nameof(scope));
+ }
+
+ Context.Attach(scope);
+ Context.Entry(scope).State = EntityState.Modified;
+
+ try
+ {
+ await Context.SaveChangesAsync(cancellationToken);
+ }
+
+ catch (DbUpdateConcurrencyException) { }
+ }
}
}
\ No newline at end of file
diff --git a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs
index 3dc76866..bb31e34b 100644
--- a/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs
+++ b/src/OpenIddict.EntityFrameworkCore/Stores/OpenIddictTokenStore.cs
@@ -90,6 +90,26 @@ namespace OpenIddict.EntityFrameworkCore
///
protected DbSet Tokens => Context.Set();
+ ///
+ /// Determines the number of tokens that match the specified query.
+ ///
+ /// The result type.
+ /// The query to execute.
+ /// The that can be used to abort the operation.
+ ///
+ /// A that can be used to monitor the asynchronous operation,
+ /// whose result returns the number of tokens that match the specified query.
+ ///
+ public override Task CountAsync([NotNull] Func, IQueryable> query, CancellationToken cancellationToken)
+ {
+ if (query == null)
+ {
+ throw new ArgumentNullException(nameof(query));
+ }
+
+ return query.Invoke(Tokens).LongCountAsync();
+ }
+
///
/// Creates a new token.
///
@@ -113,7 +133,7 @@ namespace OpenIddict.EntityFrameworkCore
}
///
- /// Creates a new token, which is associated with a particular subject.
+ /// Creates a new token.
///
/// The token descriptor.
/// The that can be used to abort the operation.
diff --git a/src/OpenIddict.Models/OpenIddictScope.cs b/src/OpenIddict.Models/OpenIddictScope.cs
index 10c9c6c4..5def77a9 100644
--- a/src/OpenIddict.Models/OpenIddictScope.cs
+++ b/src/OpenIddict.Models/OpenIddictScope.cs
@@ -36,5 +36,11 @@ namespace OpenIddict.Models
/// associated with the current scope.
///
public virtual TKey Id { get; set; }
+
+ ///
+ /// Gets or sets the unique name
+ /// associated with the current scope.
+ ///
+ public virtual string Name { get; set; }
}
}