Table of Contents

Class IdentityDbContextBase<TUser, TRole, TIdentityKey>

Namespace
NuvTools.Security.Identity.EntityFrameworkCore
Assembly
NuvTools.Security.Identity.EntityFrameworkCore.dll

Provides a base implementation of IdentityDbContext<TUser, TRole, TKey> with enhanced transaction support, execution strategies, and batch operation capabilities.

public abstract class IdentityDbContextBase<TUser, TRole, TIdentityKey> : IdentityDbContext<TUser, TRole, TIdentityKey>, IInfrastructure<IServiceProvider>, IDbContextDependencies, IDbSetCache, IDbContextPoolable, IResettableService, IDisposable, IAsyncDisposable, IDbContextCommands, IDbContextWithListCommands where TUser : IdentityUser<TIdentityKey> where TRole : IdentityRole<TIdentityKey> where TIdentityKey : IEquatable<TIdentityKey>

Type Parameters

TUser

The type representing a user in the system, must inherit from IdentityUser<TKey>.

TRole

The type representing a role in the system, must inherit from IdentityRole<TKey>.

TIdentityKey

The type of the primary key for users and roles, must implement IEquatable<T>.

Inheritance
IdentityUserContext<TUser, TIdentityKey, IdentityUserClaim<TIdentityKey>, IdentityUserLogin<TIdentityKey>, IdentityUserToken<TIdentityKey>, IdentityUserPasskey<TIdentityKey>>
IdentityDbContext<TUser, TRole, TIdentityKey, IdentityUserClaim<TIdentityKey>, IdentityUserRole<TIdentityKey>, IdentityUserLogin<TIdentityKey>, IdentityRoleClaim<TIdentityKey>, IdentityUserToken<TIdentityKey>, IdentityUserPasskey<TIdentityKey>>
IdentityDbContext<TUser, TRole, TIdentityKey, IdentityUserClaim<TIdentityKey>, IdentityUserRole<TIdentityKey>, IdentityUserLogin<TIdentityKey>, IdentityRoleClaim<TIdentityKey>, IdentityUserToken<TIdentityKey>>
IdentityDbContext<TUser, TRole, TIdentityKey>
IdentityDbContextBase<TUser, TRole, TIdentityKey>
Implements
Inherited Members

Examples

public class ApplicationDbContext : IdentityDbContextBase<ApplicationUser, ApplicationRole, Guid>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        // Configure your entities here
    }
}

Remarks

This abstract base class extends IdentityDbContext<TUser, TRole, TKey> and implements IDbContextCommands and IDbContextWithListCommands to provide:

  • Transaction management with begin, commit, and rollback operations
  • Execution strategies for handling transient database failures
  • Convenient CRUD operations that automatically save changes and return IResult wrappers
  • Batch operations for synchronizing collections of entities
  • Support for composite key operations

All operations use the Result pattern, returning IResult or IResult<T> instead of throwing exceptions for business logic failures.

Constructors

IdentityDbContextBase()

Initializes a new instance of the IdentityDbContextBase<TUser, TRole, TIdentityKey> class.

protected IdentityDbContextBase()

Remarks

This parameterless constructor is typically used for design-time tools and migrations.

IdentityDbContextBase(DbContextOptions)

Initializes a new instance of the IdentityDbContextBase<TUser, TRole, TIdentityKey> class with the specified options.

protected IdentityDbContextBase(DbContextOptions options)

Parameters

options DbContextOptions

The options to be used by the DbContext.

Remarks

This constructor is used for runtime configuration and dependency injection scenarios.

Properties

CurrentTransaction

Gets the current active transaction, or null if no transaction is active.

public IDbContextTransaction? CurrentTransaction { get; }

Property Value

IDbContextTransaction

An IDbContextTransaction representing the current transaction, or null if no transaction has been started.

Remarks

Use this property to check whether a transaction is currently active before performing transaction-specific operations.

Methods

AcquireTransactionLockAsync(string, CancellationToken)

Acquires an exclusive, database-wide lock identified by name, held until the current transaction commits or rolls back.

public Task AcquireTransactionLockAsync(string name, CancellationToken cancellationToken = default)

Parameters

name string

Lock name. Identifies what is being serialized, e.g. "contract-number:53".

cancellationToken CancellationToken

A CancellationToken to observe while waiting for the task to complete.

Returns

Task

A task that completes once the lock is held.

Remarks

The provider-specific statement is resolved from IDbContextTransactionLock, registered by the provider package's AddDatabase helpers. When none is registered (e.g. an in-memory context built by hand in a test) the call is a no-op.

Exceptions

ArgumentException

Thrown when name is null, empty or whitespace.

InvalidOperationException

Thrown when there is no active transaction.

AddAndSaveAsync<TEntity, TKey>(TEntity, CancellationToken)

Asynchronously adds an entity to the database and saves the changes, returning the generated primary key.

public Task<IResult<TKey>> AddAndSaveAsync<TEntity, TKey>(TEntity entity, CancellationToken cancellationToken = default) where TEntity : class

Parameters

entity TEntity

The entity instance to add to the database.

cancellationToken CancellationToken

A CancellationToken to observe while waiting for the task to complete.

Returns

Task<IResult<TKey>>

A task that represents the asynchronous operation. The task result contains an IResult<T> with the generated primary key value if successful.

Type Parameters

TEntity

The type of entity to add. Must be a reference type.

TKey

The type of the primary key.

Remarks

This method automatically calls SaveChangesAsync(CancellationToken) after adding the entity. The result will contain the primary key value generated by the database (for identity columns or sequences).

AddAndSaveWithCompositeKeyAsync<TEntity>(TEntity, CancellationToken)

Asynchronously adds an entity with a composite key to the database and saves the changes, returning the composite key values.

public Task<IResult<object[]>> AddAndSaveWithCompositeKeyAsync<TEntity>(TEntity entity, CancellationToken cancellationToken = default) where TEntity : class

Parameters

entity TEntity

The entity instance to add to the database.

cancellationToken CancellationToken

A CancellationToken to observe while waiting for the task to complete.

Returns

Task<IResult<object[]>>

A task that represents the asynchronous operation. The task result contains an IResult<T> with an array of composite key values if successful.

Type Parameters

TEntity

The type of entity to add. Must be a reference type.

Remarks

This method is used for entities that have composite primary keys (multiple columns forming the primary key). The returned array contains the key values in the order they are defined in the entity configuration.

AddOrRemoveFromListAsync<TEntity, TKey>(IEnumerable<TEntity>, Func<TEntity, TKey>, Expression<Func<TEntity, bool>>?, CancellationToken)

Asynchronously adds new entities from a collection or removes existing ones that are not in the collection, without updating existing entities.

public Task<IResult> AddOrRemoveFromListAsync<TEntity, TKey>(IEnumerable<TEntity> entities, Func<TEntity, TKey> keySelector, Expression<Func<TEntity, bool>>? filter = null, CancellationToken cancellationToken = default) where TEntity : class where TKey : notnull

Parameters

entities IEnumerable<TEntity>

The collection of entities to ensure exist in the database.

keySelector Func<TEntity, TKey>

A function to extract the key from an entity for comparison.

filter Expression<Func<TEntity, bool>>

An optional filter expression to limit which database entities are considered for removal.

cancellationToken CancellationToken

A CancellationToken to observe while waiting for the task to complete.

Returns

Task<IResult>

A task that represents the asynchronous operation. The task result contains an IResult indicating whether the operation was successful.

Type Parameters

TEntity

The type of entity to add or remove. Must be a reference type.

TKey

The type of the key used to identify entities. Must be non-nullable.

Examples

// Ensure specific tags exist for a post without updating existing tag data
var tags = new[] { "C#", "ASP.NET", "EF Core" }.Select(t => new Tag { Name = t, PostId = postId });
await context.AddOrRemoveFromListAsync(tags, t => t.Name, t => t.PostId == postId);

Remarks

This method performs selective add/remove operations:

  • Entities in the collection but not in the database are added
  • Entities in the database (matching the filter) but not in the collection are removed
  • Existing entities that are in both the collection and database are left unchanged (not updated)

This is useful when you only care about the presence of entities, not their current values.

AddOrUpdateFromListAsync<TEntity, TKey>(IEnumerable<TEntity>, Func<TEntity, TKey>, Expression<Func<TEntity, bool>>?, CancellationToken)

Asynchronously adds new entities from a collection or updates existing ones, without removing any entities.

public Task<IResult> AddOrUpdateFromListAsync<TEntity, TKey>(IEnumerable<TEntity> entities, Func<TEntity, TKey> keySelector, Expression<Func<TEntity, bool>>? filter = null, CancellationToken cancellationToken = default) where TEntity : class where TKey : notnull

Parameters

entities IEnumerable<TEntity>

The collection of entities to add or update in the database.

keySelector Func<TEntity, TKey>

A function to extract the key from an entity for comparison.

filter Expression<Func<TEntity, bool>>

An optional filter expression to limit which database entities are considered for matching.

cancellationToken CancellationToken

A CancellationToken to observe while waiting for the task to complete.

Returns

Task<IResult>

A task that represents the asynchronous operation. The task result contains an IResult indicating whether the operation was successful.

Type Parameters

TEntity

The type of entity to add or update. Must be a reference type.

TKey

The type of the key used to identify entities. Must be non-nullable.

Examples

// Add or update permissions without removing existing ones
var permissions = new[] { "Read", "Write", "Execute" }.Select(p => new Permission { Name = p });
await context.AddOrUpdateFromListAsync(permissions, p => p.Name);

Remarks

This method performs an upsert operation:

  • Entities not found in the database are added
  • Entities found in the database are updated with values from the collection
  • No entities are removed from the database

This is useful when you want to ensure certain entities exist and are up-to-date without deleting others.

BeginTransactionAsync(CancellationToken)

Asynchronously begins a new database transaction.

public Task<IDbContextTransaction> BeginTransactionAsync(CancellationToken cancellationToken = default)

Parameters

cancellationToken CancellationToken

A CancellationToken to observe while waiting for the task to complete.

Returns

Task<IDbContextTransaction>

A task that represents the asynchronous operation. The task result contains an IDbContextTransaction that represents the started transaction.

Remarks

Transactions allow multiple database operations to be executed as a single atomic unit. Use CommitTransactionAsync(CancellationToken) to commit the transaction or RollbackTransactionAsync(CancellationToken) to roll it back.

CommitTransactionAsync(CancellationToken)

Asynchronously commits all changes made in the current transaction to the database.

public Task CommitTransactionAsync(CancellationToken cancellationToken = default)

Parameters

cancellationToken CancellationToken

A CancellationToken to observe while waiting for the task to complete.

Returns

Task

A task that represents the asynchronous operation.

Remarks

This method should be called after BeginTransactionAsync(CancellationToken) to persist the changes. If the commit fails, the transaction remains active and can be rolled back.

Exceptions

InvalidOperationException

Thrown when there is no active transaction.

ExecuteWithStrategyAsync(Func<CancellationToken, Task>, CancellationToken)

Executes an action within the configured execution strategy to handle transient database failures.

public Task ExecuteWithStrategyAsync(Func<CancellationToken, Task> action, CancellationToken cancellationToken = default)

Parameters

action Func<CancellationToken, Task>

The action to execute that takes a CancellationToken and returns a Task.

cancellationToken CancellationToken

A CancellationToken to observe while waiting for the task to complete.

Returns

Task

A task that represents the asynchronous operation.

Remarks

The execution strategy automatically retries operations that fail due to transient errors, such as temporary network issues or database deadlocks, according to the configured retry policy.

ExecuteWithStrategyAsync<T>(Func<CancellationToken, Task<T>>, CancellationToken)

Executes a function within the configured execution strategy to handle transient database failures.

public Task<T> ExecuteWithStrategyAsync<T>(Func<CancellationToken, Task<T>> action, CancellationToken cancellationToken = default)

Parameters

action Func<CancellationToken, Task<T>>

The function to execute that takes a CancellationToken and returns a Task<TResult>.

cancellationToken CancellationToken

A CancellationToken to observe while waiting for the task to complete.

Returns

Task<T>

A task that represents the asynchronous operation. The task result contains the value returned by the function.

Type Parameters

T

The type of the result returned by the function.

Remarks

The execution strategy automatically retries operations that fail due to transient errors, such as temporary network issues or database deadlocks, according to the configured retry policy.

RemoveAndSaveAsync<TEntity>(params object[])

Asynchronously removes an entity from the database by its primary key and saves the changes.

public Task<IResult> RemoveAndSaveAsync<TEntity>(params object[] keyValues) where TEntity : class

Parameters

keyValues object[]

The primary key values identifying the entity to remove.

Returns

Task<IResult>

A task that represents the asynchronous operation. The task result contains an IResult indicating whether the removal was successful.

Type Parameters

TEntity

The type of entity to remove. Must be a reference type.

Remarks

This method finds the entity by its primary key, removes it, and automatically saves the changes. If the entity is not found, the operation may still succeed (idempotent deletion).

RemoveAndSaveAsync<TEntity>(object[], CancellationToken)

Asynchronously removes an entity from the database by its primary key and saves the changes.

public Task<IResult> RemoveAndSaveAsync<TEntity>(object[] keyValues, CancellationToken cancellationToken = default) where TEntity : class

Parameters

keyValues object[]

The primary key values identifying the entity to remove.

cancellationToken CancellationToken

A CancellationToken to observe while waiting for the task to complete.

Returns

Task<IResult>

A task that represents the asynchronous operation. The task result contains an IResult indicating whether the removal was successful.

Type Parameters

TEntity

The type of entity to remove. Must be a reference type.

Remarks

This method finds the entity by its primary key, removes it, and automatically saves the changes. If the entity is not found, the operation may still succeed (idempotent deletion).

RollbackTransactionAsync(CancellationToken)

Asynchronously rolls back all changes made in the current transaction.

public Task RollbackTransactionAsync(CancellationToken cancellationToken = default)

Parameters

cancellationToken CancellationToken

A CancellationToken to observe while waiting for the task to complete.

Returns

Task

A task that represents the asynchronous operation.

Remarks

This method discards all changes made within the current transaction and closes it. After rolling back, you need to call BeginTransactionAsync(CancellationToken) to start a new transaction.

Exceptions

InvalidOperationException

Thrown when there is no active transaction.

SyncFromListAsync<TEntity, TKey>(IEnumerable<TEntity>, Func<TEntity, TKey>, Expression<Func<TEntity, bool>>?, CancellationToken)

Asynchronously synchronizes a collection of entities with the database by adding new entities, updating existing ones, and removing entities not present in the collection.

public Task<IResult> SyncFromListAsync<TEntity, TKey>(IEnumerable<TEntity> entities, Func<TEntity, TKey> keySelector, Expression<Func<TEntity, bool>>? filter = null, CancellationToken cancellationToken = default) where TEntity : class where TKey : notnull

Parameters

entities IEnumerable<TEntity>

The collection of entities to synchronize with the database.

keySelector Func<TEntity, TKey>

A function to extract the key from an entity for comparison.

filter Expression<Func<TEntity, bool>>

An optional filter expression to limit which database entities are considered for synchronization.

cancellationToken CancellationToken

A CancellationToken to observe while waiting for the task to complete.

Returns

Task<IResult>

A task that represents the asynchronous operation. The task result contains an IResult indicating whether the synchronization was successful.

Type Parameters

TEntity

The type of entity to synchronize. Must be a reference type.

TKey

The type of the key used to identify entities. Must be non-nullable.

Examples

// Synchronize user roles - adds new, updates existing, removes missing
var userRoles = newRoleIds.Select(roleId => new IdentityUserRole<Guid> { UserId = userId, RoleId = roleId });
await context.SyncFromListAsync(userRoles, ur => ur.RoleId, ur => ur.UserId == userId);

Remarks

This method performs a full synchronization:

  • Entities in the collection but not in the database are added
  • Entities in both the collection and database are updated with values from the collection
  • Entities in the database (matching the filter) but not in the collection are removed

This is useful for maintaining master-detail relationships or synchronizing complete lists.

UpdateAndSaveAsync<TEntity>(TEntity, params object[])

Asynchronously updates an existing entity in the database and saves the changes.

public Task<IResult> UpdateAndSaveAsync<TEntity>(TEntity entity, params object[] keyValues) where TEntity : class

Parameters

entity TEntity

The entity instance with updated values.

keyValues object[]

The primary key values used to locate the existing entity in the database.

Returns

Task<IResult>

A task that represents the asynchronous operation. The task result contains an IResult indicating whether the update was successful.

Type Parameters

TEntity

The type of entity to update. Must be a reference type.

Remarks

This method finds the entity by its primary key, updates its values, and automatically saves the changes. If the entity is not found, the operation will fail and return an unsuccessful result.

UpdateAndSaveAsync<TEntity>(TEntity, object[], CancellationToken)

Asynchronously updates an existing entity in the database and saves the changes.

public Task<IResult> UpdateAndSaveAsync<TEntity>(TEntity entity, object[] keyValues, CancellationToken cancellationToken = default) where TEntity : class

Parameters

entity TEntity

The entity instance with updated values.

keyValues object[]

The primary key values used to locate the existing entity in the database.

cancellationToken CancellationToken

A CancellationToken to observe while waiting for the task to complete.

Returns

Task<IResult>

A task that represents the asynchronous operation. The task result contains an IResult indicating whether the update was successful.

Type Parameters

TEntity

The type of entity to update. Must be a reference type.

Remarks

This method finds the entity by its primary key, updates its values, and automatically saves the changes. If the entity is not found, the operation will fail and return an unsuccessful result.